自定义python列表排序

Custom Python list sorting

我在重构我的一些旧代码时遇到了:

1
2
3
4
5
6
7
8
9
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()来实现自定义排序。有人能解释一下为什么会这样吗?


作为补充说明,这里是实现相同排序的更好选择:

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

或者:

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

看看如何排序,这是非常有用的。


这里有记录。

The sort() method takes optional arguments for controlling the
comparisons.

cmp specifies a custom comparison function of two arguments (list
items) which should return a negative, zero or positive number
depending on whether the first argument is considered smaller than,
equal to, or larger than the second argument: cmp=lambda x,y:
cmp(x.lower(), y.lower()). The default value is None.


就像这个例子。你要对这个列表排序。

1
[('c', 2), ('b', 2), ('a', 3)]

输出:

1
[('a', 3), ('b', 2), ('c', 2)]

您应该按第二项对元组排序,然后按第一项排序:

1
2
3
4
5
6
7
8
9
10
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

最后:

只不过是EDOCX1[0]


这在Python3中不起作用。

但是,您可以使用functools cmp_to_key让旧的样式比较函数工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
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)