2.30. Comprehensions¶
Eine Comprehension erstellt aus einem bestehenden iterierbaren Objekt eine neue Liste, Menge, ein neues Dictionary oder einen neuen Generator in einem einzigen Ausdruck. Sie ist ein Ersatz für das gängige Muster, mit einem leeren Container zu beginnen und in einer Schleife anzuhängen.
2.30.1. List-Comprehensions¶
squares = [x * x for x in range(5)]
print(squares)
Ausgabe:
[0, 1, 4, 9, 16]
Dieselbe Schleife ausgeschrieben:
squares = []
for x in range(5):
squares.append(x * x)
Die Comprehension-Form ist ein einziger Ausdruck, der die Liste an Ort und Stelle erstellt. Es gibt kein squares = [] und kein .append – das Ergebnis ist der Wert der Comprehension.
Der führende Ausdruck erzeugt jedes Element; die for-Klausel benennt die Schleifenvariable; ein optionales if filtert Elemente heraus.¶
2.30.2. Filtern mit if¶
Eine optionale if-Klausel behält nur die Elemente, die passen:
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
Ausgabe:
[0, 2, 4, 6, 8]
Der Filter läuft vor dem führenden Ausdruck – x % 2 == 0 wird zuerst geprüft; nur passende Werte erreichen x für die Ausgabe.
2.30.3. Dict- und Set-Comprehensions¶
Dieselbe Form funktioniert mit Dict- und Set-Literalen.
Eine Dict-Comprehension hat ein key: value-Paar vor dem for:
squares = {x: x * x for x in range(5)}
print(squares)
Ausgabe:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Eine Set-Comprehension verwendet geschweifte Klammern und einen einzigen Ausdruck:
unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)
Ausgabe:
{1, 2}
2.30.4. Generator-Ausdrücke¶
Runde Klammern erzeugen einen Generator-Ausdruck statt einer Liste. Die Werte werden einzeln und bei Bedarf berechnet:
total = sum(x * x for x in range(1000))
Es wird nie eine Liste mit einer Million Elementen erstellt. Die Werte fließen einer nach dem anderen in sum(), das sie addiert und jeden verwirft, während es voranschreitet.
Generator-Ausdrücke sind die richtige Wahl, wenn Werte in eine reduzierende Funktion (sum(), max(), any(), all()) oder anderen iteratorverbrauchenden Code eingespeist werden – sie sparen den Speicher, den die entsprechende Liste belegt hätte.
2.30.5. Wann man keine Comprehension verwenden sollte¶
Comprehensions sind kompakt, aber nicht immer übersichtlicher. Greifen Sie zu einer einfachen for-Schleife, wenn:
Der Rumpf mehr als eine Anweisung benötigt (eine Comprehension fasst genau einen Ausdruck).
Der Rumpf Nebenwirkungen hat (Ausgeben, Schreiben in eine Datei) – Comprehensions dienen dem Erstellen einer Sammlung, nicht dem Ausführen von Aktionen.
Der Filter oder die Transformation so viele Teile hat, dass sich die Comprehension nicht mehr von links nach rechts liest.