30

今天早上写剧本时,我注意到了一些我没有预料到的事情。我尝试使用列表推导并将其全部排序在一个语句中,并得到了令人惊讶的结果。以下代码总结了我的一般用例,但针对此问题进行了简化:

Transaction = namedtuple('Transaction', ['code', 'type'])

my_list = [Transaction('code1', 'AAAAA'), Transaction('code2', 'BBBBB'), Transaction('code3', 'AAAAA')]

types = ['AAAAA', 'CCCCC']

result = [trans for trans in my_list if trans.type in types].sort(key = lambda x: x.code)

print result

输出:

None

如果我使用理解创建列表,然后在事后对其进行排序,一切都很好。我很好奇为什么会这样?

4

3 回答 3

51

该方法list.sort()正在对列表进行排序,并作为所有变异方法返回None。使用内置函数sorted()返回一个新的排序列表。

result = sorted((trans for trans in my_list if trans.type in types),
                key=lambda x: x.code)

取而代之的是lambda x: x.code,您也可以使用稍微快一点的operator.attrgetter("code").

于 2012-07-11T13:38:23.787 回答
4

调用.sort列表返回None。然后将此结果分配给result.

换句话说,您使用列表推导式匿名创建一个列表,然后调用.sort,列表丢失,而.sort调用结果存储在result变量中。

正如其他人所说,您应该使用sorted()内置函数来返回一个列表。(sorted()返回列表的排序副本。)

于 2012-07-11T13:39:03.817 回答
3

你想要sorted内置函数。该sort方法对列表进行就地排序并返回None

result = sorted([trans for trans in my_list if trans.type in types],key = lambda x: x.code)

这可以通过以下方式做得更好:

import operator
result = sorted( (trans for trans in my_list if trans.type in types ), key=operator.attrgetter("code"))
于 2012-07-11T13:38:08.400 回答