Menu

List comprehension w Pythonie: składnia, filtrowanie i dict comprehension

List comprehension pozwala zbudować nową listę w jednej czytelnej linii (mapowanie, filtrowanie albo jedno i drugie) zamiast wzorca pętla plus append.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Jedna linia, jedna myśl

Ten wzorzec na pewno już znasz: zaczynasz od pustej listy, przechodzisz pętlą po czymś, czasem filtrujesz i dopisujesz do wyniku.

List comprehension mówi to samo w jednej linii:

Czytaj od lewej do prawej: "nowa lista złożona z n * 2 dla każdego n w numbers". Struktura to [expression for item in iterable].

To nie jest sztuczka tylko z Pythona. Nazywa się to comprehension, bo deklaratywnie opisujesz, co trafia do nowej listy, zamiast rozpisywać mechanikę jej budowania.

Dodawanie filtra

Dopisz klauzulę if po części z pętlą, żeby filtrować:

Drugą linię czytaj tak: "n * n dla każdego n w numbers, ale tylko jeśli n jest nieparzyste".

Równoważna pętla:

Obie wersje są w porządku. Comprehension jest krótsza, a gdy przeczytasz kilka, łatwiej się ją przegląda, bo cały zamiar widać w jednej linii.

Mapowanie i filtrowanie naraz

Możesz przepuszczać wartości przez funkcję i jednocześnie filtrować:

Dla każdego słowa dłuższego niż 3 litery dodaj jego wersję pisaną wielkimi literami.

Zagnieżdżone pętle w comprehension

Dwa for dają pary w stylu iloczynu kartezjańskiego:

Kolejność jest taka sama jak przy zagnieżdżonych pętlach: pierwszy for jest zewnętrzny, drugi wewnętrzny. Czyta się to od lewej do prawej, tak jak odpowiadającą temu pętlę z wcięciami.

Dwa poziomy to mniej więcej granica, za którą zwykła pętla czyta się lepiej. Jeśli dochodzisz do trzech, wróć do pętli.

Dict comprehension i set comprehension

Ten sam pomysł, inne nawiasy:

Na pierwszy rzut oka set comprehension wygląda identycznie jak dict comprehension. Różnica to key: value zamiast pojedynczego wyrażenia. Klamry z : to słownik; klamry bez : to zbiór.

Wyrażenia generatorowe

To niemal bliźniak list comprehension, tylko z nawiasami okrągłymi zamiast kwadratowych i, co najważniejsze, nie buduje listy:

Zauważ, że generator trafił bezpośrednio do sum() i any(), bez dodatkowych nawiasów. Wyrażenia generatorowe to właściwe narzędzie, gdy wywołujący musi przejść po wynikach tylko raz. Przy dużych kolekcjach oszczędzają pamięć w porównaniu z pełną listą.

Kiedy lepiej użyć zwykłej pętli

Comprehensions kuszą. Technicznie da się w nie wcisnąć mnóstwo rzeczy. Nie warto.

Sięgnij po zwykłą pętlę, gdy:

  • Przekształcenie ma więcej niż jeden krok. Jeśli potrzebujesz zmiennych pośrednich, rozpisz to.
  • Jest w nim złożona obsługa błędów albo rozgałęzienia.
  • Każdy, kto czyta tę linię, musi zatrzymać się więcej niż raz, żeby ją zrozumieć.

Zasada, którą stosuję: jeśli potrafię przeczytać comprehension jednym tchem i zrozumieć, co robi, zostaje. Jeśli się potykam, przepisuję ją na pętlę.

Niektóre comprehensions wyglądają sprytnie, ale szkodzą:

Ten sam wynik. Wersja z pętlą ma pięć linii zamiast jednej, ale "dłuższe" nie znaczy "gorsze".

Kilka wzorców, które będziesz powtarzać

Te wzorce pokrywają zaskakująco dużo codziennej pracy z danymi.

Co dalej

Znasz już główne typy kolekcji i comprehension, które je łączy. Następny rozdział: funkcje, czyli zamykanie zachowania w nazwanych jednostkach wielokrotnego użytku.

Najczęściej zadawane pytania

Czym jest list comprehension w Pythonie?

To zwięzła składnia do budowania nowej listy z istniejącego obiektu iterowalnego. [x * 2 for x in numbers] tworzy nową listę, w której każda liczba jest podwojona. Możesz też filtrować: [x for x in numbers if x > 0].

Kiedy nie używać list comprehension?

Wtedy, gdy szkodzi czytelności. Jeśli wyrażenie w środku jest skomplikowane albo mocno zagnieżdżone, zwykła pętla for z dobrymi nazwami zmiennych jest jaśniejsza. Comprehensions są do prostych przekształceń: mapowania i filtrowania. Wszystko bardziej złożone lepiej wygląda w pełnej pętli.

Czym różni się list comprehension od wyrażenia generatorowego?

List comprehension buduje całą listę w pamięci. Wyrażenie generatorowe (ta sama składnia, ale w nawiasach okrągłych) zwraca po jednym elemencie naraz. Używaj generatora, gdy wyniki trafiają do czegoś, co przechodzi po nich raz, na przykład do sum(...), żeby nie tworzyć listy, którą zaraz wyrzucisz.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ