Python自定义字符串排序函数,如';季节年';
我有一份“季节年”表格的清单:Python自定义字符串排序函数,如';季节年';,python,sorting,Python,Sorting,我有一份“季节年”表格的清单: [“2014年秋季”、“2015年春季”、“2008年秋季”、“2008年春季”] 排序后,列表应如下所示: ['2015年春季'、'2014年秋季'、'2008年春季'、'2008年秋季'] 因此,排序规则如下: 一年一类 按季节排序:“春天”然后“秋天” 我目前有一个名为lcmp的函数,我在列表中使用它:myList.sort(lcmp) 这适用于按年份排序,但不适用于季节,即使我已经指定了排序类型。为什么会发生这种情况?只需使用-year将sort by y
[“2014年秋季”、“2015年春季”、“2008年秋季”、“2008年春季”]
排序后,列表应如下所示:
['2015年春季'、'2014年秋季'、'2008年春季'、'2008年秋季']
因此,排序规则如下:
lcmp
的函数,我在列表中使用它:myList.sort(lcmp)
这适用于按年份排序,但不适用于季节,即使我已经指定了排序类型。为什么会发生这种情况?只需使用
-year
将sort by year作为第一个键和seas!=“弹簧”
使用key=sort\u功能来断开连接
l = ['Fall 2014', 'Spring 2015', 'Fall 2008', 'Spring 2008']
def key(x):
seas,year = x.split()
return -int(year), seas != "Spring"
l.sort(key=key)
即使在传递单个字符串时使用myList.sort(key=lcmp)
,函数也无法工作,因此不需要拆分a和b。这也适用于python 2或3。您还应该考虑比较值相等的情况:
def lcmp(a,b):
c = a.split()
d = b.split()
if c[1] > d[1]:
return 1
elif c[1] == d[1]:
if c[0] > d[0]:
return -1
elif c[0] == d[0]:
return 0
else:
return 1
else:
return -1
然后可以使用myList.sort(lcmp)
或myList.sort(cmp=lcmp)
对数据进行排序。错误之一是没有正确检查是否相等。当c[1]
和c[0]
时返回什么?答案是零,这是不正确的。您还应该按排序声明cmp
参数。您可以执行以下操作:
seasons = {
'Spring': 1,
'Summer': 2,
'Fall': 3,
'Winter': 4,
}
def lcmp(a, b):
a_season, a_year = a.split()
b_season, b_year = b.split()
return int(b_year) - int(a_year) or seasons[a_season] - seasons[b_season]
l = ['Fall 2014', 'Spring 2015', 'Fall 2008', 'Spring 2008']
l.sort(cmp=lcmp)
结果:
['Spring 2015', 'Fall 2014', 'Spring 2008', 'Fall 2008']
如果您想使用迭代器:
from itertools import ifilter, izip
def lcmp(a, b):
it = (
f(y) - f(x)
for x, y, f in izip(
reversed(a.split()),
reversed(b.split()),
(int, lambda _: -seasons[_])
)
)
return next(ifilter(None, it), 0)
或者只是使用不同的键函数进行两次排序,这似乎是文档推荐的。这是因为sort()
是稳定的,并且能够利用近分类的优势。很好,对于seas
来说,可能iterable的索引包含季节@Kasramvd,我不确定我是否明白?@PadraicCunningham是的,无论如何,这太棒了!我喜欢这个角色seas!=“春天”
没关系!经过一个漫长的夜晚,我阅读有困难!删除我的评论。
from itertools import ifilter, izip
def lcmp(a, b):
it = (
f(y) - f(x)
for x, y, f in izip(
reversed(a.split()),
reversed(b.split()),
(int, lambda _: -seasons[_])
)
)
return next(ifilter(None, it), 0)