Comprehensions w Pythonie

Comprehensions (z ang. zrozumienie, pojmowanie)  to taki Thermomix dla Pythona.
Wyobraź sobie jedną linijkę kodu, która bierze jakąś strukturę iterowalną, rzuca na nią if-a, pętlę for i przy okazji jeszcze wykonuje na każdym (albo i nie każdym) elemencie jakąś operację. No proszę ja ciebie, toć to Thermomixowa-struktura jak się patrzy!

Ale pewnie nic nie rozumiesz z tego słowotoku. Dlatego zacznijmy od początku.

!UWAGA! Nie dam rady, skręca mnie, ale muszę to spolszczyć. Dlatego będę to nazywać “komprehensją” i niech świat płonie! Ale to tylko tak między nami, bo poważni programiści to pewnie by nas za to wyśmiali… 😉

Co to te komprehensje

Komprehensje to sposób tworzenia nowych kolekcji (takich jak listy, słowniki, zbiory) z istniejących struktur danych – ale zamiast pisać kilka linijek kodu, wszystko robimy w jednej, zwięzłej formie. Komprehensje pozwalają filtrować dane, przekształcać je, a nawet wykonywać złożone operacje – wszystko w bardzo pythonowym stylu.

Możesz je traktować jako sprytny skrót do pętli for, często z dodatkiem warunku if. Dają Ci moc kodowania zwięzłego, ale jednocześnie czytelnego – o ile nie przesadzisz z komplikacjami.

W Pythonie mamy trzy główne typy komprehensji:

  • list comprehensions – dla list
  • dict comprehensions – dla słowników
  • set comprehensions – dla zbiorów

List Comprehensions

Komprehensja Listy to najbardziej klasyczna i najczęściej używana forma komprehensji. Dzięki nim możesz w jednej linijce kodu stworzyć nową listę na podstawie innej kolekcji, dodając przekształcenia i warunki filtrowania.

To tak, jakbyś robił smoothie: bierzesz owoce (elementy), miksujesz je (operacja) i odrzucasz zgniłe (warunek).

Przepis podstawowy jest prosty:
[operacja +  for +  element +  in +  struktura_iterowalna +  if + warunek]

Na przykład:

#komprehensja listowa dla liczb
liczby = [1, 2, 3, 5, 8, 13]
kwadraty_parzystych = [x**2 for x in liczby if x % 2 == 0]   # [4, 16]

#komprehensja listowa dla stringów
słowa = ["python", "ai", "pogadaimy"]
głośniej = [x.upper() for x in słowa if len(w) > 2]
# ['PYTHON', 'POGADAIMY']

Dict Comprehensions

Słowniki to zdecydowanie niedoceniana struktura danych – choć przecież jest idealna do przechowywania powiązań i bardzo wydajna przy wyszukiwaniu. A komprehensje słownikowe pozwalają budować słowniki szybko i elegancko.

Zamiast tworzyć pusty słownik i wypełniać go w pętli for, możesz od razu zdefiniować, co ma być kluczem, co wartością i czy dany element w ogóle ma trafić do słownika.

Przepis podstawowy jest taki sam, przy czym tym razem mamy dwie operacje, bo potrzebujemy dwóch zmiennych na wyjściu – klucza i wartości. No i nawiasy są klamrowe.

{operacja_dla_klucza: operacja_dla_wartości for element in struktura_iterowalna if warunek}
names = ["Ala", "Basia", "Celina"]
lengths = {name: len(name) for name in names}
# {'Ala': 3, 'Basia': 5, 'Celina': 6}
A jeśli iterujemy przez inny słownik:
oryginał = {'a': 1, 'b': 2, 'c': 3}
odwrócony = {wartość: klucz dla klucz, wartość in oryginał.items()}
# {1: 'a', 2: 'b', 3: 'c'}

Set Comprehensions

Nie chcę się powtarzać, ale komprehensje dla zbiorów – są takie same jak dla list i słowników! Składnia jest identyczna jak dla list, a jedyna (serio – JEDYNA) różnica to nawiasy klamrowe zamiast kwadratowych. 

Specyfiką komprehensji setów jest, że zredukuje duplikaty. To świetna opcja, gdy chcesz przekształcić dane i jednocześnie odfiltrować powtórzenia.

{operacja for element in struktura_iterowalna if warunek}
#komprehensja zestawu dla liczb
{x % 3 for x in range(10)}   # {0, 1, 2}

#komprehesja zestawu dla stringów
słowa = ["python", "ai", "pogadaimy", "ml"]
długości = {len(x) for x in słowa}   # {2, 6, 7}

!Uwaga!
Można łatwo się potknąć, jeśli nie czytamy komprehensji bardzo dokładnie. Listy mają jeden element i nawiasy kwadratowe, słowniki – dwa elementy i nawiasy klamrowe, a zestawy – jeden element i nawiasy klamrowe. 

Kiedy nie używać Comprehensions

Comprehensions są super (i zdecydowanie świadczą o klasie programisty!), ale nie wszystko trzeba robić w jednej linijce. Nie używaj ich za wszelką cenę.

Unikaj komprehensji, jeśli:

  • kod robi się nieczytelny (np. zagnieżdżona logika, kilka warunków i transformacji na raz)
  • musisz wykonywać operacje z efektem ubocznym, np. print, zapis do pliku
  • przetwarzasz bardzo duże zbiory danych i zależy Ci na oszczędności pamięci – wtedy lepsze będą generatory.

Podsumowanie

Komprehensje to jeden z najbardziej charakterystycznych i eleganckich elementów Pythona. Pozwalają pisać zwięzły, czytelny kod, który jednocześnie robi dużo pod maską.
Używaj ich z umiarem i tylko tam, gdzie naprawdę warto.

Podziel się swoją opinią

Jeden komentarz

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *