自定义Python列表排序

时间:2012-08-07 16:39:43

标签: python list sorting

我正在重构我的一些旧代码并且遇到了这个问题:

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()来实现自定义排序。有人能解释为什么会这样吗?

6 个答案:

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

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