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?
Calling
.sort
on a list returnsNone
. It makes perfect sense that this result is then assigned toresult
.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 theresult
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.)you want the
sorted
builtin function. Thesort
method sorts a list in place and returnsNone
.this could be done slightly better by:
The method
list.sort()
is sorting the list in place, and as all mutating methods it returnsNone
. Use the built-in functionsorted()
to return a new sorted list.Instead of
lambda x: x.code
, you could also use the slightly fasteroperator.attrgetter("code")
.