Python 排序 - 对象列表
我想如果可以的话,使用 somelist.sort() 这个方法来实现这个功能。
我有一个列表,里面包含一些对象,这些对象都有一个叫 resultType 的成员变量,它是一个整数。我想用这个数字来对列表进行排序。
我该怎么做呢?
谢谢!
4 个回答
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函数,这样会更清晰。
11
当然,你不一定非得用lambda(匿名函数)。任何传入的函数,比如下面这个,也可以用。
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 排序
所以,在你的情况下……
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)
刚才提到的lambda确实是最简洁的写法,但你也可以使用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'))
74
somelist.sort(key = lambda x: x.resultType)
这里有另一种常见的方法来做同样的事情:
import operator
s.sort(key = operator.attrgetter('resultType'))
如果你还没看过的话,可能还想了解一下 sorted
。这个方法不会改变原来的列表,而是会返回一个新的已排序的列表。