List Comprehension
Python List Comprehension: Syntax, Filterung, verschachtelte Schleifen, Dict- und Set Comprehensions mit ausführbaren Beispielen.
Python List Comprehension
List Comprehension ist eine kompakte Methode, eine neue Liste zu erstellen, indem ein Ausdruck auf jedes Element eines Iterables angewendet wird — optional gefiltert durch eine Bedingung — alles in einer einzigen, lesbaren Zeile. Diese Seite behandelt die vollständige Syntax, gängige Muster, Dict- und Set Comprehensions sowie Hinweise darauf, wann eine gewöhnliche for-Schleife die bessere Wahl ist.
Syntax
Die allgemeine Form einer List Comprehension lautet:
new_list = [expression for item in iterable if condition]| Teil | Rolle |
|---|---|
expression | Wert, der für jedes item in die neue Liste aufgenommen wird |
item | Schleifenvariable, die nacheinander jeden Wert aus iterable annimmt |
iterable | Beliebige Sequenz oder Iterable: Liste, Tupel, string, range usw. |
if condition | Optionaler Filter — nur Elemente, bei denen die Bedingung True ist, werden aufgenommen |
Der Teil if condition ist optional. Wenn er weggelassen wird, erzeugt jedes Element des Iterables einen Eintrag in der neuen Liste.
Grundlegendes Beispiel: Zahlen quadrieren
Die entsprechende for-Schleife benötigt drei Zeilen; List Comprehension erledigt dasselbe in einer:
Filtern mit einer Bedingung
Füge nach dem Iterable eine if-Klausel hinzu, um nur die Elemente zu behalten, die eine Bedingung erfüllen:
Beliebige Prädikate lassen sich kombinieren. Zum Beispiel, um Wörter mit mehr als vier Zeichen zu behalten:
words = ['hi', 'hello', 'world', 'python', 'ai']
long_words = [w for w in words if len(w) > 4]
print(long_words) # ['hello', 'world', 'python']if/else im Ausdruck (Ternär)
Wenn jedes Element transformiert werden soll, aber je nach Bedingung unterschiedliche Logik angewendet werden soll, schreibe if/else in den Ausdruck (vor for), nicht hinter das Iterable:
numbers = range(1, 6)
labels = ['even' if x % 2 == 0 else 'odd' for x in numbers]
print(labels) # ['odd', 'even', 'odd', 'even', 'odd']Beachte den Unterschied:
[expr for x in it if cond]— Filter: überspringt Elemente, bei denencondFalseist[a if cond else b for x in it]— Transformation: jedes Element liefert einen Wert, der durchcondbestimmt wird
Arbeiten mit Strings
List Comprehension funktioniert mit jedem Iterable, einschließlich Strings und Listen von Strings:
words = ['hello', 'world', 'python']
upper_words = [w.upper() for w in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']Einzelne Zeichen, die eine Bedingung erfüllen, extrahieren:
vowels = [ch for ch in 'programming' if ch in 'aeiou']
print(vowels) # ['o', 'a', 'i']Verschachtelte Schleifen
List Comprehension unterstützt mehrere for-Klauseln, gleichwertig zu verschachtelten Schleifen. Das linksstehende for ist die äußere Schleife:
Ein häufiger Anwendungsfall für verschachtelte List Comprehension ist das Glätten einer 2D-Liste (Matrix) in eine 1D-Liste:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]Lesetipp: Stelle dir verschachtelte Comprehensions gedanklich als verschachtelte for-Schleifen in derselben Links-nach-rechts-Reihenfolge vor.
Dictionary Comprehension
Dieselbe Idee gilt für Dictionaries mit {} und einem key: value-Ausdruck:
keys = ['a', 'b', 'c']
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)}
print(mapping) # {'a': 1, 'b': 2, 'c': 3}Schlüssel und Werte in einem vorhandenen Dictionary vertauschen:
original = {'name': 'Alice', 'city': 'Paris'}
inverted = {v: k for k, v in original.items()}
print(inverted) # {'Alice': 'name', 'Paris': 'city'}Set Comprehension
Verwende {} mit einem einzelnen Ausdruck (ohne Doppelpunkt), um ein Set zu erstellen, das Duplikate automatisch entfernt:
numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16}Das Ergebnis ist ungeordnet (Sets haben keine garantierte Reihenfolge), verlasse dich daher nicht auf die ausgegebene Sequenz.
Performance
List Comprehensions sind im Allgemeinen schneller als entsprechende for-Schleifen, die .append() aufrufen, weil der Interpreter die interne Schleife in C optimieren kann. Zum Messen der eigenen Code-Laufzeit verwende das Modul timeit:
import timeit
loop_time = timeit.timeit(
'result = []\nfor x in range(1000):\n result.append(x**2)',
number=10000
)
comp_time = timeit.timeit(
'[x**2 for x in range(1000)]',
number=10000
)
print(f'Loop: {loop_time:.3f}s')
print(f'Comprehension: {comp_time:.3f}s')
# Comprehension is typically 20-40% fasterDer Performance-Vorteil schwindet oder verschwindet, wenn der Ausdruck selbst langsam ist (Netzwerk-I/O, aufwändige Berechnung). Profiling vor Optimierungen ist empfehlenswert.
Wann stattdessen eine einfache for-Schleife verwenden
List Comprehension ist nicht immer das richtige Werkzeug:
| Situation | Empfehlung |
|---|---|
| Einzelne Transformation oder Filterung | List Comprehension |
| Mehrere Seiteneffekte pro Iteration (Logging, Zustandsmutation) | for-Schleife |
| Komplexe Logik, die mehrere Anweisungen erfordert | for-Schleife |
| Tief verschachtelte Comprehensions (mehr als zwei Ebenen) | for-Schleife — Lesbarkeit gewinnt |
| Das Ergebnis wird nie gespeichert (nur Iteration benötigt) | Generator-Ausdruck ((x for x in ...)) |
Das deutlichste Signal, zur for-Schleife zurückzukehren, ist, wenn man die Comprehension angestrengt lesen muss, um zu verstehen, was sie tut.
Fallstricke
Variablenlecks treten in Python 3 nicht auf. Die Schleifenvariable in einer Comprehension ist auf die Comprehension selbst beschränkt:
x = 'original'
result = [x * 2 for x in range(3)]
print(x) # 'original' — not overwritten by the comprehension's xTief verschachtelte Comprehensions vermeiden. Mehr als zwei for-Klauseln in einer einzigen Comprehension beeinträchtigen die Lesbarkeit ohne nennenswerten Nutzen. Teile sie in benannte Zwischenlisten oder for-Schleifen auf.
Generator-Ausdrücke sparen Speicher. Wenn das Ergebnis nur einmal iteriert werden soll (z. B. zur Übergabe an sum() oder max()), ersetze [] durch (), um einen Generator zu erhalten, der Elemente einzeln liefert:
total = sum(x ** 2 for x in range(1, 1001))
print(total) # 333833500