Zum Inhalt springen
Python Anfänger 2 min

List Comprehensions in Python

Lerne List Comprehensions, Dictionary Comprehensions und Generator Expressions -- die elegante Art, Daten in Python zu transformieren.

Aktualisiert:

Was sind List Comprehensions?

List Comprehensions sind eine kompakte Schreibweise, um neue Listen aus bestehenden Daten zu erstellen. Sie sind eines der beliebtesten Features von Python.

Statt:

# Klassisch mit for-Schleife
quadrate = []
for x in range(10):
    quadrate.append(x ** 2)

print(quadrate)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Schreibst du einfach:

# Mit List Comprehension
quadrate = [x ** 2 for x in range(10)]

print(quadrate)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Das Ergebnis ist identisch, aber der Code ist kuerzer, lesbarer und schneller.


Grundsyntax

Die Grundform einer List Comprehension:

[ausdruck for variable in iterable]
  • ausdruck: Was in die neue Liste kommt (Transformation).
  • variable: Der Name fuer jedes Element.
  • iterable: Die Quelle der Daten.

Einfache Beispiele

# Zahlen verdoppeln
verdoppelt = [x * 2 for x in range(6)]
print(verdoppelt)  # [0, 2, 4, 6, 8, 10]

# Strings in Grossbuchstaben umwandeln
namen = ["anna", "bob", "clara"]
gross = [name.upper() for name in namen]
print(gross)  # ['ANNA', 'BOB', 'CLARA']

# Laenge jedes Strings berechnen
woerter = ["Hallo", "Welt", "Python", "Programmierung"]
laengen = [len(wort) for wort in woerter]
print(laengen)  # [5, 4, 6, 15]

# Temperatur von Celsius zu Fahrenheit
celsius = [0, 10, 20, 30, 40]
fahrenheit = [(c * 9/5) + 32 for c in celsius]
print(fahrenheit)  # [32.0, 50.0, 68.0, 86.0, 104.0]

Mit Bedingung: Filtern

Du kannst eine if-Bedingung hinzufuegen, um Elemente zu filtern:

[ausdruck for variable in iterable if bedingung]

Beispiele

# Nur gerade Zahlen
gerade = [x for x in range(20) if x % 2 == 0]
print(gerade)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# Nur positive Zahlen
zahlen = [5, -3, 8, -1, 0, 7, -4]
positiv = [x for x in zahlen if x > 0]
print(positiv)  # [5, 8, 7]

# Nur Woerter mit mehr als 4 Buchstaben
woerter = ["Hi", "Hallo", "Welt", "Python", "OK"]
lang = [w for w in woerter if len(w) > 4]
print(lang)  # ['Hallo', 'Python']

# Nur Zahlen aus einem gemischten Text extrahieren
zeichen = "a1b2c3d4e5"
ziffern = [z for z in zeichen if z.isdigit()]
print(ziffern)  # ['1', '2', '3', '4', '5']

Mit if-else im Ausdruck

Beachte den Unterschied: if zum Filtern steht am Ende, if-else zur Transformation steht im Ausdruck:

# if zum Filtern (am Ende):
gerade = [x for x in range(10) if x % 2 == 0]
print(gerade)  # [0, 2, 4, 6, 8]

# if-else zur Transformation (im Ausdruck):
labels = ["gerade" if x % 2 == 0 else "ungerade" for x in range(6)]
print(labels)  # ['gerade', 'ungerade', 'gerade', 'ungerade', 'gerade', 'ungerade']

# Negative Zahlen durch 0 ersetzen
zahlen = [5, -3, 8, -1, 0, 7]
bereinigt = [x if x >= 0 else 0 for x in zahlen]
print(bereinigt)  # [5, 0, 8, 0, 0, 7]

# Absolute Werte berechnen (ohne abs())
absolut = [x if x >= 0 else -x for x in zahlen]
print(absolut)  # [5, 3, 8, 1, 0, 7]

Vergleich: for-Schleife vs Comprehension

Hier siehst du den Unterschied in der Lesbarkeit:

Beispiel 1: Quadratzahlen

# for-Schleife (4 Zeilen)
quadrate = []
for x in range(10):
    quadrate.append(x ** 2)

# Comprehension (1 Zeile)
quadrate = [x ** 2 for x in range(10)]

Beispiel 2: Filtern und Transformieren

# for-Schleife (5 Zeilen)
ergebnis = []
for name in namen:
    if len(name) > 3:
        ergebnis.append(name.upper())

# Comprehension (1 Zeile)
ergebnis = [name.upper() for name in namen if len(name) > 3]

Beispiel 3: Verschachtelte Logik

noten = [1.3, 2.7, 4.5, 1.0, 3.3, 5.0, 2.0]

# for-Schleife
bestanden = []
for note in noten:
    if note <= 4.0:
        bestanden.append(note)

# Comprehension
bestanden = [note for note in noten if note <= 4.0]
print(bestanden)  # [1.3, 2.7, 1.0, 3.3, 2.0]

Verschachtelte Comprehensions

Du kannst auch verschachtelte Schleifen in einer Comprehension ausdruecken:

# Alle Kombinationen
farben = ["rot", "gruen"]
groessen = ["S", "M", "L"]

# for-Schleife
kombinationen = []
for farbe in farben:
    for groesse in groessen:
        kombinationen.append(f"{farbe}-{groesse}")

# Comprehension
kombinationen = [f"{farbe}-{groesse}" for farbe in farben for groesse in groessen]
print(kombinationen)
# ['rot-S', 'rot-M', 'rot-L', 'gruen-S', 'gruen-M', 'gruen-L']

Die Reihenfolge in der Comprehension entspricht der Reihenfolge der verschachtelten Schleifen: Die aeussere Schleife kommt zuerst.

Matrix erstellen

# 3x3 Matrix mit Nullen
matrix = [[0 for spalte in range(3)] for zeile in range(3)]
print(matrix)  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# Identitaetsmatrix
identitaet = [[1 if i == j else 0 for j in range(3)] for i in range(3)]
for zeile in identitaet:
    print(zeile)
# [1, 0, 0]
# [0, 1, 0]
# [0, 0, 1]

Matrix flach machen (flatten)

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Verschachtelte Schleife
flach = []
for zeile in matrix:
    for element in zeile:
        flach.append(element)

# Comprehension
flach = [element for zeile in matrix for element in zeile]
print(flach)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Dictionary Comprehensions

Genau wie Listen kannst du auch Dictionaries mit Comprehensions erstellen:

{schluessel: wert for variable in iterable}

Beispiele

# Quadratzahlen als Dictionary
quadrate = {x: x ** 2 for x in range(6)}
print(quadrate)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Woerter und ihre Laengen
woerter = ["Python", "Java", "C", "JavaScript"]
laengen = {wort: len(wort) for wort in woerter}
print(laengen)  # {'Python': 6, 'Java': 4, 'C': 1, 'JavaScript': 10}

# Celsius zu Fahrenheit
celsius_werte = [0, 10, 20, 30, 40]
temp_dict = {c: round((c * 9/5) + 32, 1) for c in celsius_werte}
print(temp_dict)  # {0: 32.0, 10: 50.0, 20: 68.0, 30: 86.0, 40: 104.0}

Filtern in Dictionary Comprehensions

noten = {"Anna": 1.3, "Bob": 4.7, "Clara": 2.0, "David": 5.0, "Eva": 1.7}

# Nur bestandene Studierende
bestanden = {name: note for name, note in noten.items() if note <= 4.0}
print(bestanden)  # {'Anna': 1.3, 'Clara': 2.0, 'Eva': 1.7}

# Schluessel und Werte tauschen
getauscht = {note: name for name, note in noten.items()}
print(getauscht)  # {1.3: 'Anna', 4.7: 'Bob', 2.0: 'Clara', 5.0: 'David', 1.7: 'Eva'}

Dictionary aus zwei Listen erstellen

schluessel = ["name", "alter", "stadt"]
werte = ["Anna", 25, "Berlin"]

person = {s: w for s, w in zip(schluessel, werte)}
print(person)  # {'name': 'Anna', 'alter': 25, 'stadt': 'Berlin'}

# Noch einfacher mit dict():
person = dict(zip(schluessel, werte))
print(person)  # {'name': 'Anna', 'alter': 25, 'stadt': 'Berlin'}

Set Comprehensions

Sets (Mengen) haben keine Duplikate. Set Comprehensions verwenden geschweifte Klammern:

{ausdruck for variable in iterable}

Beispiele

# Eindeutige Quadratzahlen
zahlen = [1, 2, 2, 3, 3, 3, 4]
quadrate = {x ** 2 for x in zahlen}
print(quadrate)  # {16, 1, 4, 9} -- keine Duplikate, ungeordnet

# Alle Vokale in einem Text
text = "Programmieren lernen macht Spass"
vokale = {z.lower() for z in text if z.lower() in "aeiou"}
print(vokale)  # {'a', 'e', 'i', 'o'}

# Eindeutige Wortlaengen
saetze = ["Hallo Welt", "Python ist toll", "Programmieren macht Spass"]
wort_laengen = {len(wort) for satz in saetze for wort in satz.split()}
print(wort_laengen)  # {3, 4, 5, 14, ...}

Generator Expressions — Kurze Einfuehrung

Generator Expressions sehen aus wie List Comprehensions, verwenden aber runde Klammern statt eckiger:

# List Comprehension -- erstellt sofort die gesamte Liste im Speicher
quadrate_liste = [x ** 2 for x in range(1000000)]

# Generator Expression -- berechnet Werte erst bei Bedarf
quadrate_gen = (x ** 2 for x in range(1000000))

Der Unterschied

# Liste: Alle Werte sofort im Speicher
liste = [x ** 2 for x in range(5)]
print(liste)        # [0, 1, 4, 9, 16]
print(type(liste))  # <class 'list'>

# Generator: Werte werden "on-the-fly" berechnet
gen = (x ** 2 for x in range(5))
print(gen)           # <generator object ...>
print(type(gen))     # <class 'generator'>

# Generator-Werte abrufen
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 4

# Oder in einer Schleife
for wert in gen:
    print(wert)   # 9, 16 (die restlichen Werte)

Wann Generator statt Liste?

# Perfekt fuer sum(), min(), max() -- kein Klammer-Doppel noetig!
summe = sum(x ** 2 for x in range(1000000))
print(summe)

maximum = max(len(wort) for wort in ["Hallo", "Welt", "Python"])
print(maximum)  # 6

# Pruefen, ob eine Bedingung fuer mindestens ein Element gilt
zahlen = [2, 4, 6, 7, 8]
hat_ungerade = any(x % 2 != 0 for x in zahlen)
print(hat_ungerade)  # True

# Pruefen, ob eine Bedingung fuer ALLE Elemente gilt
alle_positiv = all(x > 0 for x in zahlen)
print(alle_positiv)  # True

Generator Expressions sind speichereffizient — sie halten nicht alle Werte gleichzeitig im Speicher. Ideal fuer grosse Datenmengen.


Wann Comprehensions, wann normale Schleifen?

Verwende Comprehensions, wenn:

  • Du eine neue Liste/Dict/Set aus bestehenden Daten erstellst.
  • Die Logik in eine Zeile passt und lesbar bleibt.
  • Du Elemente transformieren oder filtern willst.
# Perfekt fuer Comprehensions:
quadrate = [x ** 2 for x in range(10)]
positiv = [x for x in zahlen if x > 0]
namen_dict = {name: len(name) for name in namen}

Verwende normale Schleifen, wenn:

  • Du Seiteneffekte hast (print, Datei schreiben, etc.).
  • Die Logik komplex ist (mehrere Bedingungen, verschachtelte Logik).
  • Du kein neues Objekt erstellst, sondern etwas anderes tust.
  • Die Comprehension schwer lesbar waere.
# Besser als normale Schleife:
for datei in dateien:
    verarbeite(datei)
    speichere_ergebnis(datei)

# NICHT als Comprehension! (Seiteneffekte, kein Rueckgabewert)
# [verarbeite(datei) for datei in dateien]  # Anti-Pattern!

Performance-Vorteile

List Comprehensions sind in der Regel schneller als aequivalente for-Schleifen:

import time

n = 1_000_000

# for-Schleife
start = time.time()
ergebnis1 = []
for x in range(n):
    ergebnis1.append(x ** 2)
zeit_for = time.time() - start

# Comprehension
start = time.time()
ergebnis2 = [x ** 2 for x in range(n)]
zeit_comp = time.time() - start

print(f"for-Schleife:    {zeit_for:.4f}s")
print(f"Comprehension:   {zeit_comp:.4f}s")
print(f"Speedup:         {zeit_for / zeit_comp:.1f}x")

Typisches Ergebnis: Comprehensions sind 20-30% schneller, weil Python sie intern optimiert (der append()-Aufruf entfaellt).


Lesbarkeit: Nicht uebertreiben!

Comprehensions sind maechtig, aber Lesbarkeit geht vor:

Gut lesbar

# Einfache Transformation
preise_netto = [100, 200, 350, 500]
preise_brutto = [preis * 1.19 for preis in preise_netto]

# Einfacher Filter
erwachsene = [p for p in personen if p["alter"] >= 18]

Noch OK

# Transformation + Filter
rabatt_preise = [preis * 0.9 for preis in preise if preis > 100]

Zu komplex — lieber eine normale Schleife

# SCHLECHT: Zu verschachtelt und schwer lesbar
ergebnis = [
    f"{v}-{n}" for v in vornamen for n in nachnamen
    if len(v) > 3 and n[0] == v[0] and (v, n) not in ausnahmen
]

# BESSER: Normale Schleife mit klarer Struktur
ergebnis = []
for v in vornamen:
    for n in nachnamen:
        if len(v) > 3 and n[0] == v[0]:
            if (v, n) not in ausnahmen:
                ergebnis.append(f"{v}-{n}")

Faustregel

Wenn du die Comprehension nicht in 5 Sekunden verstehst, schreib eine normale Schleife.


Praxis-Beispiele

Textverarbeitung

# Saetze bereinigen und filtern
rohdaten = ["  Hallo Welt  ", "", "  Python  ", "   ", "  Code  "]
bereinigt = [s.strip() for s in rohdaten if s.strip()]
print(bereinigt)  # ['Hallo Welt', 'Python', 'Code']

# Woerter zaehlen
text = "Python ist toll und Python ist einfach"
wort_haeufigkeit = {}
for wort in text.lower().split():
    wort_haeufigkeit[wort] = wort_haeufigkeit.get(wort, 0) + 1
# Oder als Comprehension (mit Counter):
from collections import Counter
wort_haeufigkeit = Counter(text.lower().split())
print(dict(wort_haeufigkeit))

Daten transformieren

# CSV-Daten verarbeiten
csv_zeilen = [
    "Anna,25,Berlin",
    "Bob,30,Hamburg",
    "Clara,22,Muenchen"
]

personen = [
    {"name": z.split(",")[0], "alter": int(z.split(",")[1]), "stadt": z.split(",")[2]}
    for z in csv_zeilen
]
print(personen)

# Nur Personen ueber 24
aeltere = [p for p in personen if p["alter"] > 24]
print(aeltere)

Mathematische Operationen

# Fibonacci-aehnlich: Quadratzahlen, die durch 3 teilbar sind
ergebnis = [x ** 2 for x in range(1, 21) if (x ** 2) % 3 == 0]
print(ergebnis)  # [9, 36, 81, 144, 225, 324]

# Pythagoraeische Tripel bis 20
tripel = [
    (a, b, c)
    for a in range(1, 21)
    for b in range(a, 21)
    for c in range(b, 21)
    if a ** 2 + b ** 2 == c ** 2
]
print(tripel)
# [(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15)]

Verschluesseln / Entschluesseln

# Einfache Caesar-Verschluesselung
def caesar(text, verschiebung):
    return "".join(
        chr((ord(z) - ord('a') + verschiebung) % 26 + ord('a'))
        if z.isalpha() and z.islower()
        else z
        for z in text
    )

verschluesselt = caesar("hallo welt", 3)
print(verschluesselt)  # "kdoor zhow"

entschluesselt = caesar(verschluesselt, -3)
print(entschluesselt)  # "hallo welt"

Uebungen

Uebung 1: Gerade Quadrate

Erstelle mit einer List Comprehension eine Liste aller Quadratzahlen von 1 bis 20, die gerade sind.

Loesung anzeigen
gerade_quadrate = [x ** 2 for x in range(1, 21) if (x ** 2) % 2 == 0]
print(gerade_quadrate)  # [4, 16, 36, 64, 100, 144, 196, 256, 324, 400]

Uebung 2: Initialen

Erstelle aus einer Liste von vollen Namen eine Liste der Initialen.

namen = ["Max Mustermann", "Anna Schmidt", "Bob Mueller"]
# Erwartet: ["MM", "AS", "BM"]
Loesung anzeigen
namen = ["Max Mustermann", "Anna Schmidt", "Bob Mueller"]
initialen = ["".join(teil[0] for teil in name.split()) for name in namen]
print(initialen)  # ['MM', 'AS', 'BM']

Uebung 3: Wort-Laengen-Dictionary

Erstelle ein Dictionary, das Woerter auf ihre Laenge abbildet. Filtere Woerter mit weniger als 4 Buchstaben heraus.

satz = "Python ist eine großartige Programmiersprache fuer Anfaenger"
# Erwartet: {'Python': 6, 'eine': 4, ...}
Loesung anzeigen
satz = "Python ist eine grossartige Programmiersprache fuer Anfaenger"
wort_laengen = {wort: len(wort) for wort in satz.split() if len(wort) >= 4}
print(wort_laengen)
# {'Python': 6, 'eine': 4, 'grossartige': 11, 'Programmiersprache': 18, 'fuer': 4, 'Anfaenger': 9}

Uebung 4: Matrix-Transposition

Transponiere eine Matrix (Zeilen und Spalten tauschen) mit einer verschachtelten List Comprehension.

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
# Erwartet: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Loesung anzeigen
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

transponiert = [[zeile[i] for zeile in matrix] for i in range(len(matrix[0]))]
for zeile in transponiert:
    print(zeile)
# [1, 4, 7]
# [2, 5, 8]
# [3, 6, 9]

Uebung 5: Verschachtelt zu Flach

Erstelle eine Comprehension, die eine verschachtelte Liste von Zahlen flach macht und nur die geraden Zahlen behaelt.

verschachtelt = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
# Erwartet: [2, 4, 6, 8, 10, 12]
Loesung anzeigen
verschachtelt = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
flach_gerade = [x for gruppe in verschachtelt for x in gruppe if x % 2 == 0]
print(flach_gerade)  # [2, 4, 6, 8, 10, 12]

Pro-Tipp: Comprehensions debuggen

Wenn eine Comprehension nicht das tut, was du erwartest, wandle sie zurueck in eine for-Schleife und fuge print()-Aufrufe ein:

# Diese Comprehension liefert unerwartete Ergebnisse?
ergebnis = [x ** 2 for x in range(10) if x % 3 == 0]

# Zum Debuggen aufloesen:
ergebnis = []
for x in range(10):
    print(f"x={x}, x%3={x%3}, x**2={x**2}")
    if x % 3 == 0:
        ergebnis.append(x ** 2)
        print(f"  -> Hinzugefuegt: {x**2}")

print(ergebnis)

Wenn du die Schleife verstanden und den Fehler behoben hast, kannst du sie wieder zur Comprehension zusammenfassen.

Zurück zum Python Kurs