Сортировка понимания списка в одном заявлении
Я заметил то, чего не ожидал при написании script сегодня утром. Я попытался использовать понимание списка и отсортировать его в одном заявлении и получил неожиданный результат. Следующий код обобщает мой общий прецедент, но упрощен для этого вопроса:
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
Если я создаю список с использованием понимания, то сортируйте его после факта, все в порядке. Мне любопытно, почему это происходит?
Ответы
Ответ 1
Метод 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")
.
Ответ 2
Вызов .sort
в списке возвращает None
. Имеет смысл, что этот результат затем присваивается result
.
Другими словами, вы создаете список анонимно со списком, затем вызываете .sort
, и список теряется, когда результат вызова .sort
сохраняется в переменной result
.
Как говорили другие, вы должны использовать встроенную функцию sorted()
, чтобы вернуть список. (sorted()
возвращает отсортированную копию списка.)
Ответ 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"))