2.30. Sažeti zapisi (comprehensions)

Sažeti zapis (comprehension) gradi novu listu, skup, rječnik ili generator iz postojeće iterabilne strukture, u jednom izrazu. To je zamjena za uobičajeni obrazac u kojem se počinje s praznim spremnikom i dodaje u petlji.

2.30.1. Sažeti zapisi liste

squares = [x * x for x in range(5)]
print(squares)

Izlaz:

[0, 1, 4, 9, 16]

Ista petlja ispisana u potpunosti:

squares = []
for x in range(5):
    squares.append(x * x)

Oblik sažetog zapisa je jedan izraz koji gradi listu na mjestu. Nema squares = [] ni .append – rezultat je vrijednost sažetog zapisa.

Izraz "[f(x) for x in xs if cond]" s objašnjenjima: vodeći izraz je rezultat, klauzula for imenuje varijablu petlje, klauzula if filtrira koji se elementi zadržavaju.

Vodeći izraz proizvodi svaki element; klauzula for imenuje varijablu petlje; neobavezni if izbacuje elemente.

2.30.2. Filtriranje pomoću if

Neobavezna klauzula if zadržava samo elemente koji odgovaraju:

evens = [x for x in range(10) if x % 2 == 0]
print(evens)

Izlaz:

[0, 2, 4, 6, 8]

Filtar se izvršava prije vodećeg izraza – x % 2 == 0 provjerava se prvo; samo vrijednosti koje odgovaraju dospijevaju do x za izlaz.

2.30.3. Sažeti zapisi rječnika i skupa

Isti oblik radi s literalima rječnika i skupa.

Sažeti zapis rječnika ima par key: value prije for:

squares = {x: x * x for x in range(5)}
print(squares)

Izlaz:

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Sažeti zapis skupa koristi vitičaste zagrade i jedan izraz:

unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)

Izlaz:

{1, 2}

2.30.4. Generatorski izrazi

Obične zagrade proizvode generatorski izraz umjesto liste. Vrijednosti se računaju jedna po jedna, na zahtjev:

total = sum(x * x for x in range(1000))

Lista od milijun elemenata nikad se ne gradi. Vrijednosti teku jedna po jedna u sum(), koja ih zbraja i odbacuje svaku usput.

Generatorski izrazi pravi su izbor kada vrijednosti predajete redukcijskoj funkciji (sum(), max(), any(), all()) ili bilo kojem drugom kodu koji troši iterator – štede memoriju koju bi ekvivalentna lista zauzela.

2.30.5. Kada ne koristiti sažeti zapis

Sažeti zapisi su koncizni, ali ne uvijek jasniji. Posegnite za običnom for petljom kada:

  • Tijelo treba više od jedne naredbe (sažeti zapis stane točno jedan izraz).

  • Tijelo ima nuspojave (ispisivanje, pisanje u datoteku) – sažeti zapisi služe za izgradnju kolekcije, a ne za izvođenje akcija.

  • Filtar ili transformacija ima toliko dijelova da se sažeti zapis više ne čita slijeva nadesno.