2012-07-11 31 views
11

Zauważyłem coś, czego nie spodziewałem się, pisząc dziś rano scenariusz. Próbowałem użyć rozumowania z list i posortowałem je w jednym komunikacie i uzyskałem zaskakujący wynik. Poniższy kod podsumowuje mój ogólny przypadek użycia, ale jest uproszczone na to pytanie:Sortowanie listy w jednym komunikacie

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 

wyjściowa:

None 

Jeśli utworzyć listę za pomocą słuchu, następnie posortować je po fakcie, wszystko jest w porządku. Jestem ciekawy, dlaczego tak się dzieje?

+2

Metoda 'sort' sortuje listę * w miejscu *, a następnie zwraca' Brak'. – sloth

Odpowiedz

21

Metoda list.sort() jest sortowanie listy na miejscu, jak i wszystkich metod mutującymi zwraca None. Użyj wbudowanej funkcji sorted(), aby zwrócić nową posortowaną listę.

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

Zamiast lambda x: x.code, można również użyć nieco szybciej operator.attrgetter("code").

0

chcesz wbudowaną funkcję sorted. Metoda sort sortuje listę w miejscu i zwraca None.

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

można to zrobić nieco lepiej:

import operator 
result = sorted((trans for trans in my_list if trans.type in types), key=operator.attrgetter("code")) 
+0

Należy zauważyć, że przekazanie rozumienia listy do 'posortowanego()' powoduje wykonanie kopii tworzonej listy. To niekoniecznie jest wolniejsze, ale może spowodować większe zużycie pamięci. –

+0

Musisz ująć wyrażenie generatora w nawiasach. –

+0

@SvenMarnach - Nie potrzebujesz nawiasów? 'posortowane (x dla x w xrange (10))' działa dobrze dla mnie – mgilson

2

Wywołanie .sort na liście zwraca None. Ma to doskonały sens, że ten wynik zostanie następnie przypisany do result.

Innymi słowy, należy utworzyć listę anonimowo z listy ze zrozumieniem, a potem zadzwonić .sort, a lista jest tracona podczas wynikiem połączenia .sort jest przechowywany w zmiennej result.

Jak powiedzieli inni, powinieneś użyć wbudowanej funkcji sorted(), aby zwrócić listę. (sorted() zwraca posortowaną kopię listy.)

Powiązane problemy