Wer aus Java, C# oder JavaScript zu Python wechselt, sucht oft nach einem eigenen foreach-Befehl. Den gibt es nicht, weil Python diese Aufgabe mit einer besonders direkten for-Schleife löst. Ich zeige, wie die Iteration über Listen, Dictionaries, Zeichenketten und andere Iterable funktioniert, wann enumerate() oder zip() sinnvoll sind und welche Fehler in der Praxis häufig auftreten.
Die Python-Schleife macht Iteration einfach und lesbar
-
Kein eigenes Schlüsselwort nötig:
forübernimmt die foreach-Aufgabe. - Iterable Objekte wie Listen, Strings, Dictionaries, Mengen und Dateien können direkt durchlaufen werden.
-
enumerate()liefert Index und Wert, ohne dassrange(len(...))nötig ist. -
zip()verarbeitet mehrere Datenquellen parallel und kann mitstrict=TrueLängenfehler aufdecken. -
break,continueundelsesteuern den Ablauf einer Schleife präzise.
Python foreach entspricht der for-Schleife
Die grundlegende Syntax ist bewusst kurz gehalten. Eine Variable nimmt bei jedem Durchlauf das nächste Element aus einem Iterable auf. Ein Iterable ist ein Objekt, dessen Werte nacheinander gelesen werden können.
farben = ["Rot", "Grün", "Blau"]
for farbe in farben:
print(farbe)
Die Ausgabe lautet Rot, Grün und Blau. Anders als bei einer klassischen Zählschleife muss ich keinen Startwert, keine Abbruchbedingung und keinen Zähler manuell verwalten. Python arbeitet die Elemente in ihrer vorhandenen Reihenfolge ab und beendet die Schleife automatisch.
Die Einrückung gehört dabei zur Syntax. Alle Zeilen mit derselben Einrückung bilden den Schleifenkörper. Ich verwende konsequent vier Leerzeichen und vermeide Tabs, weil gemischte Einrückungen unnötige Syntaxfehler verursachen.
Was intern passiert
Python holt sich aus dem Objekt einen Iterator. Dieser liefert mit jedem Schleifendurchlauf den nächsten Wert, bis keine Elemente mehr vorhanden sind. Deshalb funktioniert dieselbe Struktur nicht nur mit Listen, sondern auch mit Generatoren, Dateien oder selbst definierten Objekten.
for zeichen in "Python":
print(zeichen)
Hier wird jeder Buchstabe einzeln verarbeitet. Gerade bei Zeichenketten ist das praktisch, etwa wenn ich Zeichen prüfen oder zählen möchte. Eine Schleife über einen Generator kann außerdem große Datenmengen verarbeiten, ohne alle Werte gleichzeitig im Speicher abzulegen.
Listen, Dictionaries und andere Iterable richtig durchlaufen
Bei Listen ist die direkte Iteration fast immer die beste Wahl. Ich greife auf den Wert selbst zu und nicht auf seinen Index. Das macht den Code kürzer und verhindert typische Fehler bei leeren Listen oder falschen Indexgrenzen.
temperaturen = [18, 21, 23, 19]
for temperatur in temperaturen:
if temperatur >= 20:
print(f"{temperatur} °C sind angenehm.")
Für eine reine Zahlenfolge verwende ich range(). Der Endwert gehört nicht zur erzeugten Folge. Deshalb liefert range(5) die Werte 0 bis 4.
for nummer in range(1, 6):
print(nummer)
Mit drei Argumenten lassen sich Startwert, Endwert und Schritt festlegen. range(10, 0, -2) erzeugt beispielsweise 10, 8, 6, 4 und 2. Das Objekt erzeugt die Werte erst beim Durchlaufen und muss keine vollständige Liste im Speicher anlegen.
Dictionaries durchlaufen
Bei einem Dictionary durchläuft for standardmäßig die Schlüssel. Das ist nützlich, wird aber von Einsteigern oft falsch eingeschätzt.
preise = {"Buch": 24.90, "Tastatur": 79.00}
for artikel in preise:
print(artikel)
Benötige ich Schlüssel und Wert, ist .items() die klare Variante. Für ausschließlich Werte nutze ich .values(). Die Einfügereihenfolge von Dictionaries ist in modernen Python-Versionen garantiert, trotzdem sollte die Reihenfolge nur dann fachlich relevant sein, wenn sie bewusst Teil der Datenlogik ist.
for artikel, preis in preise.items():
print(f"{artikel}: {preis:.2f} Euro")
Mengen und Dateien
Eine Menge, also ein set, kann ebenfalls durchlaufen werden. Dabei gibt es jedoch keine verlässliche fachliche Reihenfolge. Wenn die Reihenfolge zählt, sortiere ich die Werte vorher mit sorted().
berechtigungen = {"lesen", "schreiben", "löschen"}
for recht in sorted(berechtigungen):
print(recht)
Dateien lassen sich zeilenweise lesen, ohne den gesamten Inhalt auf einmal zu laden. Das ist für große Protokolle oder Messdaten deutlich besser als ein pauschales read().
with open("messwerte.txt", encoding="utf-8") as datei:
for zeile in datei:
zeile = zeile.strip()
if zeile:
print(zeile)
Die Datei wird durch with zuverlässig geschlossen. Diese Kombination aus Kontextmanager und Schleife gehört für mich zu den saubersten Standardmustern in Python.
Mit enumerate und zip wird der Code robuster
Ein häufiger Anfängerfehler ist die manuelle Indexverwaltung. Stattdessen nutze ich enumerate(), wenn sowohl Position als auch Wert gebraucht werden.
aufgaben = ["Daten prüfen", "Bericht erstellen", "Backup starten"]
for index, aufgabe in enumerate(aufgaben, start=1):
print(f"{index}. {aufgabe}")
Der Parameter start=1 macht aus dem technischen Index 0 eine für Menschen passende Nummerierung ab 1. Dadurch wird der Code verständlicher als die oft verwendete Konstruktion mit range(len(aufgaben)).
Mit zip() lassen sich mehrere Iterable elementweise verbinden. Die erste Position der ersten Folge wird mit der ersten Position der zweiten Folge kombiniert.
namen = ["Anna", "Boris", "Clara"]
punkte = [86, 92, 78]
for name, punktzahl in zip(namen, punkte):
print(f"{name}: {punktzahl} Punkte")
Standardmäßig endet zip(), sobald das kürzeste Iterable erschöpft ist. Das ist praktisch, kann aber einen Datenfehler unbemerkt verschlucken. Wenn beide Folgen gleich lang sein müssen, verwende ich strict=True.
for name, punktzahl in zip(namen, punkte, strict=True):
print(name, punktzahl)
Bei unterschiedlich langen Folgen löst diese Variante einen ValueError aus. Der Fehler erscheint dort, wo das Problem entsteht, statt später in einer scheinbar unabhängigen Auswertung.
break, continue und else gezielt einsetzen
break beendet die innerste Schleife sofort. Das passt, wenn ich beispielsweise den ersten passenden Datensatz gefunden habe.
suchbegriffe = ["Archiv", "Bericht", "Notiz"]
for begriff in suchbegriffe:
if begriff == "Bericht":
print("Treffer gefunden")
break
continue überspringt nur den aktuellen Durchlauf. Im nächsten Durchlauf arbeitet die Schleife mit dem folgenden Element weiter.
werte = [12, -3, 8, 0, 15]
for wert in werte:
if wert <= 0:
continue
print(wert)
Die weniger bekannte else-Klausel gehört zur Schleife, nicht zum if. Sie wird ausgeführt, wenn die Schleife vollständig endet und kein break ausgelöst wurde.
dateien = ["bericht.pdf", "daten.csv", "notizen.txt"]
for datei in dateien:
if datei.endswith(".xlsx"):
print("Excel-Datei gefunden")
break
else:
print("Keine Excel-Datei vorhanden")
Dieses Muster eignet sich für Suchvorgänge. In meinen eigenen Beispielen setze ich es sparsam ein, weil ein zusätzliches Flag für viele Leser leichter zu verstehen ist. Bei einer klaren Suche ist for ... else aber elegant und vollkommen korrekt.
Welche Fehler bei Schleifen besonders häufig sind
Eine Sammlung während der Iteration verändern
Wird eine Liste oder ein Dictionary während des Durchlaufs verändert, können Elemente übersprungen werden oder die Iteration mit einem Fehler abbrechen. Ich trenne deshalb die Auswahl vom Löschen oder arbeite über eine Kopie.
werte = [1, 2, 3, 4, 5, 6]
gerade_werte = [wert for wert in werte if wert % 2 == 0]
Die neue Liste ist hier sicherer und lesbarer als das Entfernen einzelner Elemente während der Schleife. Bei einem Dictionary kann ich über eine Kopie der Einträge laufen.
status = {"Anna": "aktiv", "Boris": "inaktiv"}
for name, zustand in list(status.items()):
if zustand == "inaktiv":
del status[name]
Die falsche Schleifenform wählen
Wenn ich über Werte iteriere, ist for wert in liste fast immer besser als for i in range(len(liste)). Die Indexvariante ist nur dann sinnvoll, wenn ich tatsächlich mehrere Positionen vergleichen oder gezielt Werte ersetzen muss.
Für eine einfache Umwandlung ist eine List Comprehension oft passend. Sie erzeugt eine neue Liste in einer Zeile, sollte aber nicht so komplex werden, dass die Lesbarkeit leidet.
zahlen = [1, 2, 3, 4]
quadrate = [zahl * zahl for zahl in zahlen]
Bei sehr großen Datenmengen nutze ich stattdessen einen Generatorausdruck. Er liefert Werte nach Bedarf und spart Speicher, weil nicht sofort eine vollständige Ergebnisliste entsteht.
zahlen = range(1_000_000)
quadrate = (zahl * zahl for zahl in zahlen)
for quadrat in quadrate:
if quadrat > 100:
print(quadrat)
break
Lesen Sie auch: Binär in Dezimal umrechnen - So geht's wirklich einfach
Endlosschleifen und unnötige Arbeit vermeiden
Eine for-Schleife über ein endliches Iterable endet automatisch. Bei while muss ich die Abbruchbedingung selbst zuverlässig verändern. Für das Durchlaufen vorhandener Daten ist for meist die klarere und sicherere Wahl.
Auch verschachtelte Schleifen können teuer werden. Zwei Schleifen mit jeweils 1.000 Durchläufen ergeben im ungünstigen Fall bis zu 1.000.000 Kombinationen. Wenn Datenbanken, große Dateien oder wissenschaftliche Daten beteiligt sind, prüfe ich deshalb, ob ein Dictionary, ein Set oder eine passende Standardfunktion die Suche effizienter lösen kann.
Die passende Variante für den Alltag auswählen
| Aufgabe | Geeignete Lösung | Warum |
|---|---|---|
| Werte einer Liste verarbeiten | for wert in liste |
Direkt, lesbar und ohne manuelle Indizes |
| Position und Wert benötigen | enumerate() |
Verhindert fehleranfällige Zähler |
| Zwei Folgen paarweise lesen | zip() |
Verbindet Werte übersichtlich |
| Feste Zahlenfolge durchlaufen | range() |
Unterstützt Start, Ende und Schritt |
| Neue Liste aus vorhandenen Werten bilden | List Comprehension | Kompakt bei einfachen Bedingungen |
| Große Folge speichersparend verarbeiten | Generator oder Generatorausdruck | Erzeugt Werte erst bei Bedarf |
Für asynchrone Datenquellen gibt es außerdem async for. Das ist beispielsweise bei Netzwerkstreams oder asynchronen Datenbankzugriffen relevant. Es ersetzt keine normale Schleife, sondern passt zu Objekten, deren nächste Werte erst nach einer asynchronen Wartezeit verfügbar werden.
Meine Faustregel ist einfach. Starte mit einer direkten for-Schleife, ergänze enumerate() oder zip() nur bei echtem Bedarf und greife zu Comprehensions oder Generatoren, wenn die verkürzte Form noch gut lesbar bleibt.
Ein klares Muster für jede Python-Iteration
Die wichtigste Übersetzung lautet foreach in anderen Sprachen wird in Python normalerweise zu for element in iterable. Wer Werte direkt verarbeitet, statt unnötig mit Indizes zu hantieren, schreibt meist robusteren Code.
Bei der täglichen Arbeit helfen drei Prüfungen. Frage zuerst, ob du wirklich den Index brauchst. Prüfe danach, ob mehrere Folgen dieselbe Länge haben und ob zip(..., strict=True) sinnvoll ist. Verändere zuletzt niemals unbedacht die Sammlung, über die du gerade iterierst.
Damit deckt die Python-Schleife fast alle klassischen Iterationsaufgaben ab, bleibt gut lesbar und funktioniert vom kleinen Skript bis zur Verarbeitung großer Datenströme.