2010-07-09 50 views
37

如何使用任意函数描述的键对列表进行排序?例如,如果我有:按任意lambda排序

mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 

我想用每一个构件,例如第二元件排序“MYLIST”

sort(mylist, key=lambda x: x[1]) 

我该怎么做?

+0

当您尝试使用您提供的代码时,会出现什么问题? – tzot 2010-07-11 09:17:19

回答

37

你基本上它已经:

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> mylist.sort(key=lambda x: x[1]) 
>>> print mylist 

给出:

[['bar', 0, 'b'], ['quux', 1, 'a']] 

这将对mylist进行排序。

[本段落编辑感谢@ Daniel的更正。] sorted将返回一个新的列表,它被排序而不是实际改变输入,如http://wiki.python.org/moin/HowTo/Sorting/中所述。

+0

很好的区分,谢谢。 – user248237dfsf 2010-07-09 20:50:29

4

的答案是使用 “分类”,即

sorted(mylist, key=lambda x: x[1]) 
+0

我有参数向后。似乎不一致,例如map/filter/reduce采用lambda第一个参数并列出第二个参数,但是排序相反。 – javadba 2017-04-29 20:17:20

7

你有两个选择,非常接近你所描述的,实际上是:

mylist.sort(key=lambda x: x[1]) # In place sort 
new_list = sorted(mylist, key=lambda x: x[1]) 
9

这是一个通用的需求,对于已经添加到标准库,在operator.itemgetter形式支持:

from operator import itemgetter 
mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
mylist.sort(key=itemgetter(1)) # or sorted(mylist, key=...) 
4

排序和itemgetter是最快的。

>>> import operator 
>>> import timeit 

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> t1 = timeit.Timer(lambda: mylist.sort(key=lambda x: x[1])) 
>>> t1.timeit() 
1.6330803055632404 

>>> t2 = timeit.Timer(lambda: mylist.sort(key=operator.itemgetter(1))) 
>>> t2.timeit() 
1.3985503043467773 

>>> t3 = timeit.Timer(lambda: sorted(mylist, key=operator.itemgetter(1))) 
>>> t3.timeit() 
2.6329514733833292 

>>> t4 = timeit.Timer(lambda: sorted(mylist, key=lambda x: x[1])) 
>>> t4.timeit() 
2.9197154810598533