W3docs

Python enumerate, zip, map und filter

Lerne, wie Pythons enumerate, zip, map und filter funktionieren – mit klaren Beispielen und praktischen Mustern für saubereren Iterationscode.

Python liefert vier eingebaute Funktionen — enumerate, zip, map und filter — die häufige Schleifenmuster durch einen einzigen, lesbaren Ausdruck ersetzen. Jede gibt einen Iterator zurück (lazy, speichereffizient), und sie lassen sich natürlich mit for-Schleifen und List Comprehensions kombinieren.

Dieses Kapitel behandelt:

  • enumerate() — Schleifen mit automatischem Index
  • zip() — zwei oder mehr Sequenzen parallel durchlaufen
  • map() — eine Funktion auf jedes Element anwenden
  • filter() — nur Elemente behalten, die einen Test bestehen
  • Alle vier in realen Mustern kombinieren
  • Wann eine List Comprehension vorzuziehen ist

enumerate() — Index beim Schleifen

Wenn du während einer Schleife sowohl die Position als auch den Wert benötigst, verwendet der naive Ansatz einen manuellen Zähler:

colors = ["red", "green", "blue"]
i = 0
for color in colors:
    print(i, color)
    i += 1

enumerate() erledigt das automatisch. Es umhüllt ein beliebiges Iterable und liefert (index, value)-Paare:

colors = ["red", "green", "blue"]
for i, color in enumerate(colors):
    print(i, color)

Ausgabe:

0 red
1 green
2 blue

Von einem anderen Index starten

Übergebe ein start-Argument, um die Zählung bei einer beliebigen ganzen Zahl zu beginnen:

fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits, start=1):
    print(f"{i}. {fruit}")

Ausgabe:

1. apple
2. banana
3. cherry

Dies ist nützlich beim Erstellen nummerierter Listen für die Anzeige, bei denen 0-basierte Nummerierung für den Leser ungewohnt wirkt.

enumerate() mit einer Bedingung

Da enumerate() ein ganz normaler Iterator ist, können Bedingungen im Schleifenrumpf mit if eingebaut werden:

scores = [72, 91, 55, 88, 44]
for rank, score in enumerate(scores, start=1):
    if score >= 80:
        print(f"Rank {rank}: score {score} — PASS")

Ausgabe:

Rank 2: score 91 — PASS
Rank 4: score 88 — PASS

Nur den Index ohne enumerate() erhalten

Wenn nur ein Index und sonst nichts benötigt wird, funktioniert range(len(seq)) — sobald jedoch auch der Wert gebraucht wird, sollte enumerate() verwendet werden, um das wiederholte Schreiben von seq[i] zu vermeiden.


zip() — mehrere Sequenzen parallel durchlaufen

zip() kombiniert zwei oder mehr Iterables zu einem einzigen Iterator aus Tupeln und paart Elemente an übereinstimmenden Positionen:

names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]

for name, score in zip(names, scores):
    print(f"{name}: {score}")

Ausgabe:

Alice: 95
Bob: 87
Charlie: 92

zip() mit drei oder mehr Iterables

first = ["a", "b", "c"]
second = [1, 2, 3]
third = [True, False, True]

for x, y, z in zip(first, second, third):
    print(x, y, z)

Ausgabe:

a 1 True
b 2 False
c 3 True

Sequenzen unterschiedlicher Länge

zip() stoppt beim kürzesten Iterable und verwirft stillschweigend die verbleibenden Elemente längerer Sequenzen:

short = [1, 2]
long  = [10, 20, 30, 40]

print(list(zip(short, long)))

Ausgabe:

[(1, 10), (2, 20)]

Die Werte 30 und 40 aus long werden verworfen. Wenn alle Elemente erhalten bleiben sollen, kann itertools.zip_longest aus der Standardbibliothek verwendet werden:

from itertools import zip_longest

short = [1, 2]
long  = [10, 20, 30, 40]

print(list(zip_longest(short, long, fillvalue=0)))

Ausgabe:

[(1, 10), (2, 20), (0, 30), (0, 40)]

Ein zip-Ergebnis in eine Liste oder ein Dict umwandeln

zip() gibt einen lazy Iterator zurück. Umhülle ihn mit list(), um alle Paare auf einmal zu materialisieren, oder übergib ihn an dict(), um eine Zuordnung aus zwei parallelen Sequenzen zu erstellen:

keys   = ["name", "age", "city"]
values = ["Alice", 30, "Paris"]

record = dict(zip(keys, values))
print(record)

Ausgabe:

{'name': 'Alice', 'age': 30, 'city': 'Paris'}

Entzippen mit zip(*...)

Der *-Entpackungstrick „kehrt" eine Sequenz von Tupeln zurück in separate Sequenzen um:

pairs = [(1, "a"), (2, "b"), (3, "c")]
numbers, letters = zip(*pairs)

print(numbers)  # (1, 2, 3)
print(letters)  # ('a', 'b', 'c')

map() — eine Funktion auf jedes Element anwenden

map(function, iterable) wendet function auf jedes Element an und gibt einen lazy Iterator der Ergebnisse zurück. Es ersetzt eine for-Schleife, die eine neue Liste durch Transformation jedes Elements aufbaut.

numbers = [1, 2, 3, 4, 5]
squares = map(lambda x: x ** 2, numbers)
print(list(squares))

Ausgabe:

[1, 4, 9, 16, 25]

map() mit einer benannten Funktion

Es kann jedes Callable übergeben werden — eine eingebaute Funktion, eine mit def definierte Funktion oder eine lambda:

words = ["  hello  ", "  world  ", "  python  "]
stripped = list(map(str.strip, words))
print(stripped)

Ausgabe:

['hello', 'world', 'python']

Hier wird str.strip als Referenz übergeben (ohne Klammern). map() ruft str.strip(word) für jedes Element auf.

map() über mehrere Iterables

Übergebe weitere Iterables, um eine Funktion zu mappen, die zwei oder mehr Argumente entgegennimmt. map() durchläuft dann alle Iterables parallel (wie zip() stoppt es beim kürzesten):

a = [1, 2, 3]
b = [10, 20, 30]
totals = list(map(lambda x, y: x + y, a, b))
print(totals)

Ausgabe:

[11, 22, 33]

map() vs. List Comprehension

Beide Ansätze sind gültig. Die Faustregel:

SituationBevorzuge
Anwenden einer vorhandenen benannten Funktionmap() — kürzer, kein lambda nötig
Schreiben eines Inline-AusdrucksList Comprehension — besser lesbar
Mehrere Eingaben parallelmap() mit mehreren Iterables

Äquivalente Formen:

# map() with a named function
result = list(map(str.upper, ["a", "b", "c"]))

# list comprehension — same result
result = [s.upper() for s in ["a", "b", "c"]]

filter() — nur Elemente behalten, die eine Bedingung erfüllen

filter(function, iterable) behält Elemente, für die function einen wahren Wert zurückgibt. Es gibt einen lazy Iterator zurück.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens))

Ausgabe:

[2, 4, 6, 8, 10]

filter() mit einer benannten Funktion

def is_positive(n):
    return n > 0

values = [-3, -1, 0, 4, 7, -2]
positives = list(filter(is_positive, values))
print(positives)

Ausgabe:

[4, 7]

filter(None, iterable) — falsy-Werte entfernen

Das Übergeben von None als Funktion behält nur Werte, die truthy sind. Dies ist eine schnelle Möglichkeit, leere Strings, Nullen und None-Werte zu entfernen:

mixed = [0, "hello", "", None, 42, False, "world"]
truthy = list(filter(None, mixed))
print(truthy)

Ausgabe:

['hello', 42, 'world']

filter() vs. List Comprehension

filter() und eine bedingte List Comprehension erledigen dieselbe Aufgabe:

numbers = range(1, 11)

# filter()
evens_f = list(filter(lambda x: x % 2 == 0, numbers))

# list comprehension — equivalent
evens_c = [x for x in numbers if x % 2 == 0]

print(evens_f)  # [2, 4, 6, 8, 10]
print(evens_c)  # [2, 4, 6, 8, 10]

Bevorzuge eine List Comprehension, wenn die Bedingung inline geschrieben wird; bevorzuge filter(), wenn bereits eine gut benannte Prädikatsfunktion vorhanden ist.


enumerate, zip, map und filter kombinieren

Diese vier Funktionen lassen sich natürlich kombinieren. Hier ein realistisches Beispiel: Du hast zwei parallele Listen mit Schülernamen und Rohpunktzahlen; du möchtest einen nummerierten Bericht ausgeben, der nur Schüler enthält, die bestanden haben (Punktzahl >= 60), mit in Buchstabennoten umgerechneten Punktzahlen.

def letter_grade(score):
    if score >= 90:
        return "A"
    elif score >= 80:
        return "B"
    elif score >= 70:
        return "C"
    elif score >= 60:
        return "D"
    return "F"

names  = ["Alice", "Bob", "Carol", "Dave", "Eve"]
scores = [85, 52, 91, 67, 48]

# Step 1: pair names with scores
pairs = zip(names, scores)

# Step 2: keep only passing students
passing = filter(lambda pair: pair[1] >= 60, pairs)

# Step 3: convert scores to letter grades
graded = map(lambda pair: (pair[0], letter_grade(pair[1])), passing)

# Step 4: number the results
for rank, (name, grade) in enumerate(graded, start=1):
    print(f"{rank}. {name}: {grade}")

Ausgabe:

1. Alice: B
2. Carol: A
3. Dave: D

Jeder Schritt produziert einen Iterator; nichts wird in eine Liste materialisiert, bis die for-Schleife ihn verbraucht. Dies hält den Speicherverbrauch unabhängig von der Eingabegröße konstant.


Häufige Fallstricke

Iteratoren sind nach einem Durchlauf erschöpft

map(), filter() und zip() geben alle Iteratoren zurück, keine Listen. Sobald ein Iterator verbraucht ist, ist er leer:

squares = map(lambda x: x ** 2, [1, 2, 3])
print(list(squares))  # [1, 4, 9]
print(list(squares))  # [] — already exhausted

Umhülle ihn vorab mit list(), wenn du mehr als einmal iterieren musst.

zip() verwirft stillschweigend überschüssige Elemente

Wenn die Eingabesequenzen unterschiedliche Längen haben, verwirft zip() die zusätzlichen Elemente ohne Warnung. Überprüfe Längen explizit, wenn dies wichtig ist, oder verwende itertools.zip_longest.

enumerate() ändert das Iterable nicht

enumerate() umhüllt das ursprüngliche Iterable; es kopiert es nicht. Das Ändern der zugrunde liegenden Liste während der Iteration kann zu unerwarteten Ergebnissen führen — dieselbe Vorsicht, die für gewöhnliche for-Schleifen gilt.


Kurzreferenz

FunktionSignaturWas sie zurückgibt
enumerateenumerate(iterable, start=0)Iterator von (index, value)-Tupeln
zipzip(*iterables)Iterator von Tupeln, ein Element aus jedem Iterable pro Tupel
mapmap(function, *iterables)Iterator von function, angewendet auf jedes Element
filterfilter(function, iterable)Iterator von Elementen, bei denen function True zurückgibt

Alle vier sind lazy: Sie produzieren Werte bei Bedarf, anstatt vorab eine vollständige Liste aufzubauen.


Übungen

Übung
What does enumerate(items, start=1) do when used in a for loop?
What does enumerate(items, start=1) do when used in a for loop?
Übung
What happens when you pass sequences of different lengths to zip()?
What happens when you pass sequences of different lengths to zip()?
Übung
Which statement about map() is correct?
Which statement about map() is correct?
Übung
What does filter(None, iterable) do?
What does filter(None, iterable) do?
Was this page helpful?