我正在重构我的一些旧代码并且遇到了这个问题:
alist.sort(cmp_items)
def cmp_items(a, b):
if a.foo > b.foo:
return 1
elif a.foo == b.foo:
return 0
else:
return -1
代码可以工作(我在大约3年前写过它!)但是我无法在Python文档的任何地方找到这个东西,每个人都使用sorted()
来实现自定义排序。有人能解释为什么会这样吗?
答案 0 :(得分:84)
作为旁注,这是实现相同排序的更好选择:
alist.sort(key=lambda x: x.foo)
或者:
import operator
alist.sort(key=operator.attrgetter('foo'))
查看Sorting How To,这非常有用。
答案 1 :(得分:47)
记录here。
sort()方法采用可选参数来控制 比较。
cmp指定两个参数的自定义比较函数(list items)应返回负数,零或正数 取决于第一个参数是否被认为小于, 等于或大于第二个参数:cmp = lambda x,y: cmp(x.lower(),y.lower())。默认值为None。
答案 2 :(得分:10)
就像这个例子。你想要排序这个列表。
[('c', 2), ('b', 2), ('a', 3)]
输出:
[('a', 3), ('b', 2), ('c', 2)]
你应该按第二项排序元组,然后是第一项:
def letter_cmp(a, b):
if a[1] > b[1]:
return -1
elif a[1] == b[1]:
if a[0] > b[0]:
return 1
else:
return -1
else:
return 1
最后:
只是sort(letter_cmp)
答案 3 :(得分:3)
这在Python 3中不起作用。
您可以使用functools cmp_to_key使旧式比较功能正常工作。
from functools import cmp_to_key
def cmp_items(a, b):
if a.foo > b.foo:
return 1
elif a.foo == b.foo:
return 0
else:
return -1
cmp_items_py3 = cmp_to_key(cmp_items)
alist.sort(cmp_items_py3)
答案 4 :(得分:1)
我知道许多人已经发布了一些好的答案。但是,我想提出一种不错的简便方法,而无需导入任何库。
l = [(2, 3), (3, 4), (2, 4)]
l.sort(key = lambda x: (-x[0], -x[1]) )
print(l)
l.sort(key = lambda x: (x[0], -x[1]) )
print(l)
输出将为
[(3, 4), (2, 4), (2, 3)]
[(2, 4), (2, 3), (3, 4)]
输出将根据我们以元组格式提供的参数的顺序进行排序
答案 5 :(得分:0)
更好:
student_tuples = [
('john', 'A', 15),
('jane', 'B', 12),
('dave', 'B', 10),
]
sorted(student_tuples, key=lambda student: student[2]) # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]