2010-02-25 158 views
33

如果可能,我想使用somelist.sort()方法执行此操作。Python排序 - 对象列表

我有一个包含对象的列表,所有对象都有一个成员变量resultType,它是一个整数。我想用这个数字对列表进行排序。

我该怎么做?

谢谢!

回答

67
somelist.sort(key = lambda x: x.resultType) 

这里的另一种方式做同样的事情,你会经常看到用:

import operator 
s.sort(key = operator.attrgetter('resultType')) 

你可能也想看看sorted,如果你还没有看到它了。它不会修改原始列表 - 它会返回一个新的排序列表。

+0

你回答了我的两个问题(attrgetter ..),并指出我有用的东西。谢谢! – Art

+0

你帮我意识到排序与排序有何不同!谢谢 – gl2748

10

当然,它不一定是拉姆达。任何函数传入,如下面的一个,将工作

def numeric_compare(x, y): 
    if x > y: 
     return 1 
    elif x == y: 
     return 0 
    else: #x < y 
     return -1 

a = [5, 2, 3, 1, 4] 
a.sort(numeric_compare) 

来源:Python Sorting

所以,你的情况......

def object_compare(x, y): 
    if x.resultType > y.resultType: 
     return 1 
    elif x.resultType == y.resultType: 
     return 0 
    else: #x.resultType < y.resultType 
     return -1 

a.sort(object_compare) 

上述拉姆达绝对是最紧凑这样做的方式,但也有使用operator.itemgetter

import operator 
#L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] 
map(operator.itemgetter(0), L) 
#['c', 'd', 'a', 'b'] 
map(operator.itemgetter(1), L) 
#[2, 1, 4, 3] 
sorted(L, key=operator.itemgetter(1)) 
#[('d', 1), ('c', 2), ('b', 3), ('a', 4)] 

所以你会使用itemgetter('resultType')。 (假设的GetItem定义)

sorted(L, key=operator.itemgetter('resultType')) 
+1

cmp已被弃用 - 甚至不存在于Python3中。您应该使用键功能。 –

+1

谢谢你。我总是喜欢看非lambda方式来做事情,即使我最终会使用lambda版本(它只是感觉更性感) – NickO

+0

感谢Rizwan。比较方法很有帮助 –

1
somelist.sort(cmp = lambda x, y: cmp(x.resultType, y.resultType)) 

是优于:

somelist.sort(key = lambda x: x.resultType) 

在我们在其用于成对比较的元素的比较函数通过第一种情况下在列表中。在第二种情况下,我们分配一个新的关键函数结果和原始值对的列表。然后我们对这个列表进行排序,然后去掉对中的关键值。如果你的比较功能很昂贵,这是非常有用的,但如果比较结果非常便宜,这只会浪费内存。

也就是说,密钥版本的扩张看起来是这样的:

l = [y for x,y in sorted(zip([key(i) for i in l], l))] 

对于一个简单的按键功能,这显然是开销太大,所以不是我会建议使用较轻的基于函数的排序。

请注意,cmp函数参数需要在小于,等于和大于的情况下返回-1,0,1。你可以自己写,但你也可以使用更清晰的内置cmp函数。

+0

叹气,感谢@gnibbler,我不知道cmp param在Python 3中已被弃用,这很好理解。但是如果你使用python 2.x,我认为它比关键版本更清晰更高效。在Python 3中,我会关注Mark Byers。 –