2.30. Comprehensiuni¶
O comprehensiune construiește o nouă listă, mulțime, dicționar sau generator dintr-un iterabil existent, într-o singură expresie. Este un înlocuitor pentru tiparul comun de a porni de la un container gol și de a adăuga elemente într-o buclă.
2.30.1. Comprehensiuni de listă¶
squares = [x * x for x in range(5)]
print(squares)
Rezultat:
[0, 1, 4, 9, 16]
Aceeași buclă scrisă în detaliu:
squares = []
for x in range(5):
squares.append(x * x)
Forma de comprehensiune este o singură expresie care construiește lista pe loc. Nu există squares = [] și nici .append – rezultatul este valoarea comprehensiunii.
Expresia de la început produce fiecare element; clauza for numește variabila buclei; un if opțional filtrează elementele.¶
2.30.2. Filtrarea cu if¶
O clauză if opțională păstrează doar elementele care se potrivesc:
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
Rezultat:
[0, 2, 4, 6, 8]
Filtrul rulează înaintea expresiei de la început – x % 2 == 0 este verificat primul; doar valorile care se potrivesc ajung la x pentru rezultat.
2.30.3. Comprehensiuni de dicționar și de mulțime¶
Aceeași formă funcționează cu literalii de dicționar și de mulțime.
O comprehensiune de dicționar are o pereche key: value înaintea lui for:
squares = {x: x * x for x in range(5)}
print(squares)
Rezultat:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
O comprehensiune de mulțime folosește acolade și o singură expresie:
unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)
Rezultat:
{1, 2}
2.30.4. Expresii generator¶
Parantezele rotunde produc o expresie generator în loc de o listă. Valorile sunt calculate una câte una, la cerere:
total = sum(x * x for x in range(1000))
Nu se construiește niciodată o listă de un milion de elemente. Valorile curg una câte una către sum(), care le adună și le elimină pe măsură ce avansează.
Expresiile generator sunt alegerea potrivită atunci când alimentezi valori într-o funcție de reducere (sum(), max(), any(), all()) sau în orice alt cod care consumă un iterator – ele economisesc memoria pe care ar fi folosit-o lista echivalentă.
2.30.5. Când să nu folosești o comprehensiune¶
Comprehensiunile sunt concise, dar nu întotdeauna mai clare. Recurge la o buclă for obișnuită când:
Corpul are nevoie de mai mult de o singură instrucțiune (o comprehensiune încape exact o expresie).
Corpul are efecte secundare (afișare, scriere într-un fișier) – comprehensiunile sunt pentru construirea unei colecții, nu pentru executarea de acțiuni.
Filtrul sau transformarea are atât de multe părți încât comprehensiunea nu se mai citește de la stânga la dreapta.