2.30. Comprehensions¶
En comprehension bygger en ny lista, mängd, dict eller generator från en befintlig iterabel, i ett enda uttryck. Den ersätter det vanliga mönstret att börja med en tom behållare och lägga till i en loop.
2.30.1. List comprehensions¶
squares = [x * x for x in range(5)]
print(squares)
Utdata:
[0, 1, 4, 9, 16]
Samma loop utskriven:
squares = []
for x in range(5):
squares.append(x * x)
Comprehension-formen är ett uttryck som bygger listan på plats. Det finns inget squares = [] och inget .append – resultatet är värdet av denna comprehension.
Det inledande uttrycket producerar varje element; for-satsen namnger loopvariabeln; en valfri if filtrerar bort element.¶
2.30.2. Filtrering med if¶
En valfri if-sats behåller endast de element som matchar:
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
Utdata:
[0, 2, 4, 6, 8]
Filtret körs före det inledande uttrycket – x % 2 == 0 kontrolleras först; endast matchande värden når x för utdatan.
2.30.3. Comprehensions för dict och mängd¶
Samma form fungerar med dict- och mängdlitteraler.
En dict comprehension har ett key: value-par före for:
squares = {x: x * x for x in range(5)}
print(squares)
Utdata:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
En set comprehension använder klamrar och ett enda uttryck:
unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)
Utdata:
{1, 2}
2.30.4. Generatoruttryck¶
Vanliga parenteser producerar ett generatoruttryck i stället för en lista. Värdena beräknas ett i taget, vid behov:
total = sum(x * x for x in range(1000))
Ingen miljonelementslista byggs någonsin. Värdena flödar ett och ett in i sum(), som adderar dem och kasserar varje värde efter hand.
Generatoruttryck är rätt val när man matar in värden i en reducerande funktion (sum(), max(), any(), all()) eller någon annan kod som konsumerar en iterator – de sparar det minne som den motsvarande listan skulle ha använt.
2.30.5. När man inte ska använda en comprehension¶
Comprehensions är koncisa men inte alltid tydligare. Ta till en vanlig for-loop när:
Kroppen behöver mer än en sats (en comprehension rymmer exakt ett uttryck).
Kroppen har sidoeffekter (utskrift, skrivning till en fil) – comprehensions är till för att bygga en samling, inte för att utföra åtgärder.
Filtret eller transformationen har så många delar att denna comprehension inte längre läses från vänster till höger.