Custom Python list sorting

I was refactoring some old code of mine and came across of this:

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

The code works (and I wrote it some 3 years ago!) but I cannot find this thing documented anywhere in the Python docs and everybody uses sorted() to implement custom sorting. Can someone explain why this works?

170188 次浏览

给你的记录。

Sort ()方法采用可选参数来控制 比较。

Cmp 指定两个参数的自定义比较函数(list 条目) ,它应该返回一个负数,零或正数 取决于第一个参数是否被认为小于, 等于或大于第二个参数: cmp = lambda x,y: Cmp (x.lower () ,y.lower ()).

As a side note, here is a better alternative to implement the same sorting:

alist.sort(key=lambda x: x.foo)

或者:

import operator
alist.sort(key=operator.attrgetter('foo'))

看看 如何排序,它非常有用。

就像这个例子一样,你需要对这个列表进行排序。

[('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

然后将其转换为一个关键函数:

from functools import cmp_to_key
letter_cmp_key = cmp_to_key(letter_cmp))

现在可以使用自定义排序顺序:

[('c', 2), ('b', 2), ('a', 3)].sort(key=letter_cmp_key)

这在 Python3中不起作用。

不过,您可以使用 function tools 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)

甚至更好:

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)]

摘自: https://docs.python.org/3/howto/sorting.html

我知道很多人已经发布了一些很好的答案。然而,我想建议一个不导入任何库的好的和容易的方法。

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)]

输出将根据我们以元组格式提供的参数的顺序进行排序