2.30. Comprehensions¶
Comprehension sestaví nový list, set, dict nebo generátor z existujícího iterovatelného objektu v jediném výrazu. Je náhradou za běžný vzor, kdy začnete prázdným kontejnerem a v cyklu do něj přidáváte prvky.
2.30.1. List comprehensions¶
squares = [x * x for x in range(5)]
print(squares)
Výstup:
[0, 1, 4, 9, 16]
Tentýž cyklus rozepsaný:
squares = []
for x in range(5):
squares.append(x * x)
Forma comprehension je jediný výraz, který sestaví list rovnou na místě. Není zde žádné squares = [] ani žádné .append – výsledkem je hodnota dané comprehension.
Úvodní výraz produkuje každý prvek; klauzule for pojmenovává řídicí proměnnou cyklu; volitelná klauzule if prvky odfiltrovává.¶
2.30.2. Filtrování pomocí if¶
Volitelná klauzule if zachová pouze prvky, které vyhovují:
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
Výstup:
[0, 2, 4, 6, 8]
Filtr běží před úvodním výrazem – nejprve se ověří x % 2 == 0; do x se pro výstup dostanou pouze vyhovující hodnoty.
2.30.3. Dict a set comprehensions¶
Tentýž tvar funguje i s literály dict a set.
Dict comprehension má před for dvojici key: value:
squares = {x: x * x for x in range(5)}
print(squares)
Výstup:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Set comprehension používá složené závorky a jediný výraz:
unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)
Výstup:
{1, 2}
2.30.4. Generátorové výrazy¶
Kulaté závorky produkují místo listu generátorový výraz. Hodnoty se počítají po jedné, na vyžádání:
total = sum(x * x for x in range(1000))
Žádný milionprvkový list se nikdy nevytvoří. Hodnoty proudí jedna po druhé do sum(), která je sčítá a každou postupně zahazuje.
Generátorové výrazy jsou správnou volbou při předávání hodnot do redukční funkce (sum(), max(), any(), all()) nebo do jakéhokoli jiného kódu konzumujícího iterátory – ušetří paměť, kterou by spotřeboval ekvivalentní list.
2.30.5. Kdy comprehension nepoužít¶
Comprehensions jsou stručné, ale ne vždy přehlednější. Po prostém cyklu for sáhněte, když:
Tělo potřebuje více než jeden příkaz (do comprehension se vejde přesně jeden výraz).
Tělo má vedlejší účinky (tisk, zápis do souboru) – comprehensions slouží k sestavení kolekce, nikoli ke spouštění akcí.
Filtr nebo transformace mají tolik částí, že se comprehension už nečte zleva doprava.