我有一个Python中三个字符串的列表,例如
m = [['pig', 'quartz', '1'], ['pork', 'nails', '1'], ...]
我想按索引0排序,然后按相反顺序按索引2排序,再按索引1排序。在排序的每一步,我都希望保持其他列强加的顺序。例如,
pork barn 4
pork barn2 4
pork nails 1
pig quartz 1
quinoa pail 1
quinoa quatern 1
quail quatern 1
radish barn 1
radish barn2 1
radish inbox 3
radish snow 1
将变成:
pig quartz 1
pork barn 4
pork barn2 4
pork nails 1
quail quatern 1
quinoa pail 1
quinoa quatern 1
radish inbox 3 <-
radish barn 1
radish barn2 1
radish snow 1
也就是说,按第一列排序,然后在每组第一列(猪、猪肉、鹌鹑…)内,按第三列反向排序,然后按每组第一列第三列((猪,1)、(猪肉,4)、,按第二列排序。
我怎么能做得这么好?从概念上讲,如果operator.itemgetter()
可以将排序顺序和索引一起编码,我会想要类似m.sort(key=operator.itemgetter(0, -2, 1))
的东西。
def key(item):
return item[0], -int(item[2]), item[1]
m.sort(key = key)
PS。cmp
关键字参数已从Python3中删除。为了将来的兼容性,您可能希望继续使用key
。
我会尝试这样的东西:
def sort_key(a, b, c):
return (a, -int(c) , b)
m.sort(key = lambda row: sort_key(*row))
使用自定义比较函数:
def compare_triples(a, b):
ret=cmp(a[0], b[0])
if ret: return ret
ret=cmp(b[2], a[2])
if ret: return ret
return cmp(a[1], b[1])
for i in m: print i
print "-" * 79
m2=sorted(m, cmp=compare_triples)
for i in m2: print i
比较函数不是最优的,可以重写为:
def compare_triples(a, b):
return cmp((a[0], b[2], a[1]), (b[0], a[2], b[1]))
正如其他人所指出的,这也会奏效:
def sort_key(a):
return a[0], -int(a[2]), a[1]
for i in sorted(m, key=sort_key): print i