Sorting A List Comprehension In One Statement

2019-03-23 12:04发布

I noticed something I didn't expect when writing a script this morning. I tried to use a list comprehension and sort it all in one statement and got a surprising result. The following code summarizes my general use case, but is simplified for this question:

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

Output:

None

If I create the list using the comprehension, then sort it after the fact, everything is fine. I'm curious why this happens?

3条回答
forever°为你锁心
2楼-- · 2019-03-23 12:23

Calling .sort on a list returns None. It makes perfect sense that this result is then assigned to result.

In other words, you create a list anonymously with a list comprehension, then call .sort, and the list is lost while the result of the .sort call is stored in the result variable.

As others have said, you should use the sorted() builtin function in order to return a list. (sorted() returns a sorted copy of the list.)

查看更多
欢心
3楼-- · 2019-03-23 12:31

you want the sorted builtin function. The sort method sorts a list in place and returns None.

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

this could be done slightly better by:

import operator
result = sorted( (trans for trans in my_list if trans.type in types ), key=operator.attrgetter("code"))
查看更多
该账号已被封号
4楼-- · 2019-03-23 12:35

The method list.sort() is sorting the list in place, and as all mutating methods it returns None. Use the built-in function sorted() to return a new sorted list.

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

Instead of lambda x: x.code, you could also use the slightly faster operator.attrgetter("code").

查看更多
登录 后发表回答