for-Schleifen und range — eine bekannte Anzahl von Malen ausführen
Wenn du weißt, wie oft etwas laufen soll, ist eine for-Schleife die richtige Wahl. Die drei Formen von range, warum das Ende ausgeschlossen wird und wie du zwischen for und while entscheidest.
Wie möchtest du lernen?
Das Problem, das wir lösen
Im letzten Kapitel brauchte es vier Zeilen, um die Zahlen von 1 bis 5 zu addieren. Zwei davon gab es nur, um mitzuzählen: einen Startwert und eine Erhöhung. Vergisst du die Erhöhung, hast du eine Endlosschleife.
Aber denk an eine Sache bei dieser Art von Aufgabe: Wir wussten im Voraus, wie oft sie laufen würde. Nämlich fünfmal. In so einem Fall gibt es keinen Grund, das Zählen selbst zu übernehmen — das kannst du Python überlassen.
Genau das macht eine for-Schleife. Und weil das Zählen nicht mehr in deiner Hand liegt, kann eine for-Schleife über einen range nicht von selbst zur Endlosschleife werden — die Anzahl der Durchläufe steht fest, sobald die Schleife startet. Das ist ihr größter Vorteil. (Es gibt eine Ausnahme: Wenn du über eine Liste schleifst und innerhalb der Schleife immer wieder Elemente an genau diese Liste anhängst, endet die Schleife nie. Listen kommen im nächsten Kapitel.)
Am Ende dieses Kapitels kannst du
- Code eine bekannte Anzahl von Malen mit einer
for-Schleife ausführen - Alle drei Formen von
range()verwenden - Erklären, warum
range(1, 5)vier Zahlen liefert und nicht fünf - Über die Zeichen eines Strings schleifen
- Entscheiden, welche Schleife,
foroderwhile, für eine Aufgabe passt
Voraussetzungen: while-Schleifen — laufen, solange eine Bedingung gilt.
Die einfachste Form
for number in range(5):
print(number)0
1
2
3
4Drei Zeilen Arbeit in einer — ohne Zähler, um den du dich kümmern musst. Lies es so: „Für jede Zahl, die `range(5)` liefert, führe den Block einmal aus — und lege dabei jedes Mal diese Zahl in `number`.“
Zwei Dinge fallen sofort auf:
Es beginnt bei null, und 5 taucht nie auf — insgesamt fünf Zahlen, nämlich 0 bis 4. Das ist dieselbe Regel, die Python überall anwendet: So wie bei einem Slice das Ende ausgeschlossen wird, wird es auch bei einem range ausgeschlossen.
Der Name number ist deine Wahl. for i in range(5) ist genauso gut, und i ist der übliche Name für einen Zähler. Wenn die Zahl aber eine Bedeutung hat, benenne sie nach dieser Bedeutung — for student_number in range(30) ist auch ohne Erklärung verständlich.
Die drei Formen von range()
print("--- range(5) ---")
for i in range(5):
print(i, end=" ")
print()
print("--- range(2, 6) ---")
for i in range(2, 6):
print(i, end=" ")
print()
print("--- range(0, 10, 3) ---")
for i in range(0, 10, 3):
print(i, end=" ")
print()
print("--- range(5, 0, -1) ---")
for i in range(5, 0, -1):
print(i, end=" ")
print()--- range(5) ---
0 1 2 3 4
--- range(2, 6) ---
2 3 4 5
--- range(0, 10, 3) ---
0 3 6 9
--- range(5, 0, -1) ---
5 4 3 2 1Die Regeln:
range(stop)— beginnt bei0und endet vorstoprange(start, stop)— beginnt beistartund endet vorstoprange(start, stop, step)— erhöht bei jedem Durchlauf umstep; ein negativerstepzählt rückwärts
Prüf die letzten beiden nach. range(0, 10, 3) ergibt 0 3 6 9 — der nächste Wert wäre 12, und der liegt hinter 10, also hört es auf. Und range(5, 0, -1) ergibt 5 4 3 2 1 — 0 taucht nie auf, weil auch hier das Ende ausgeschlossen wird.
Warum wird das Ende ausgeschlossen? Weil es die Rechnung einfach macht. Wie viele Zahlen hatrange(0, 5)?5 - 0, also fünf. Undrange(3, 8)?8 - 3, also fünf. Subtrahierst du, hast du die Anzahl, ohne überlegen zu müssen, ob du noch eins addieren musst. Und zweiranges, die aneinanderstoßen —range(0, 5)undrange(5, 10)— lassen nichts aus und wiederholen nichts.
Wenn du eins bis zehn willst
Dieser Fehler passiert so oft, dass er einen eigenen Abschnitt verdient:
print("Wrong — stops at 9:")
for i in range(1, 10):
print(i, end=" ")
print()
print("Right — includes 10:")
for i in range(1, 11):
print(i, end=" ")
print()Wrong — stops at 9:
1 2 3 4 5 6 7 8 9
Right — includes 10:
1 2 3 4 5 6 7 8 9 10Die Regel in einem Satz: Schreib als stop eine Zahl mehr als die letzte, die du haben willst.
Akkumulieren — jetzt auf die einfache Art
total = 0
for number in range(1, 6):
total = total + number
print("Sum of 1 to 5:", total)Sum of 1 to 5: 15Vergleich das mit der while-Version derselben Aufgabe: kein Zähler zum Anlegen, keiner zum Erhöhen, kein Risiko einer Endlosschleife. Nur der Akkumulator muss weiterhin vor der Schleife starten, genau wie vorher.
Über einen String schleifen
for läuft nicht nur über Zahlen — es läuft auch über einen String, Zeichen für Zeichen:
word = "Python"
for letter in word:
print(letter, end="-")
print()
vowel_count = 0
for letter in "programming":
if letter in "aeiou":
vowel_count = vowel_count + 1
print("Vowels:", vowel_count)P-y-t-h-o-n-
Vowels: 3Hier brauchst du kein range, weil keins nötig ist — for letter in word geht die Zeichen direkt durch. Das ist einfacher als Indexrechnung, und es gibt keinen IndexError, der passieren könnte.
Wenn du Index und Zeichen zugleich brauchst, gibt es enumerate(); das kommt im Kapitel über Listen.
break und continue funktionieren auch hier
Genau so wie in einer while-Schleife:
for number in range(1, 20):
if number % 7 == 0:
print("First multiple of 7:", number)
breakFirst multiple of 7: 7Wahl zwischen for und while
Stell dir eine Frage: Steht die Anzahl der Wiederholungen fest, bevor die Schleife startet?
Wenn ja, for:
- Fünfmal ausführen
- Von 1 bis 100 gehen
- Jedes Zeichen eines Wortes ansehen
- Mit jedem Element einer Liste etwas tun
Wenn nein, while:
- So lange nachfragen, bis die Eingabe gültig ist
- Laufen, bis die Person
quiteintippt - Lesen, solange in einer Datei noch Zeilen übrig sind
Im Zweifel nimm for. Der Grund ist einfach: Eine for-Schleife über einen range oder einen festen String endet garantiert, eine while-Schleife nicht. Wenn beide funktionieren würden, ist die Variante, die weniger Fehler zulässt, die bessere Wahl.
Ein vollständiges Beispiel
multiplication.py:
# Print a multiplication table, then a small summary
number = int(input("Which table? "))
upto = int(input("Up to? "))
print()
print(f"--- Table of {number} ---")
total = 0
for i in range(1, upto + 1):
result = number * i
total = total + result
print(f"{number} x {i:2} = {result:4}")
print()
print(f"Rows : {upto}")
print(f"Sum : {total}")
print(f"Average : {total / upto:.2f}")Which table? 7
Up to? 5
--- Table of 7 ---
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
Rows : 5
Sum : 105
Average : 21.00Drei Dinge sind hier zu beachten. Erstens range(1, upto + 1) — damit upto erreicht wird, musste man eins mehr schreiben. Zweitens {i:2} und {result:4} — in einem f-String legst du fest, wie viele Stellen eine Zahl belegen soll, so bleiben die Spalten untereinander ausgerichtet. Drittens: total startet vor der Schleife und wächst innerhalb — derselbe Akkumulator wie vorher.
Und frag dich einmal: Was passiert, wenn die Person bei Up to? eine 0 eingibt? Das range(1, 1) liefert gar keine Zahlen, die Schleife läuft also nie — und dann teilt total / upto durch null. Es ist dieselbe Lektion wie im vorherigen Kapitel: Bevor du etwas verwendest, das eine Schleife gesammelt hat, prüf, ob überhaupt etwas gesammelt wurde.
Wenn etwas schiefgeht
Die letzte Zahl fehlt range(1, 10) endet bei 9. Erhöh den stop um eins: range(1, 11).
TypeError: 'float' object cannot be interpreted as an integer range() akzeptiert nur ganze Zahlen (int). range(2.5) oder range(1, n / 2) läuft nicht — wandle mit int() um oder teile mit //.
SyntaxError: expected ':' Der Doppelpunkt am Ende der for-Zeile fehlt.
IndentationError: expected an indented block after 'for' statement Die Zeile innerhalb der Schleife ist nicht eingerückt.
Die Schleife wurde nie ausgeführt Das range ist leer. range(5, 0) liefert nichts — um rückwärts zu zählen, brauchst du das dritte Argument: range(5, 0, -1).
Die Summe ist nach der Schleife 0 Die Zeile total = 0 steht innerhalb der Schleife, daher wird sie bei jedem Durchlauf zurückgesetzt. Sie muss davor stehen.
Eine Variable, die nach der Schleife gebraucht wird, löst einen NameError aus Das range war leer, die Schleife lief also nie, und die Variable wurde nie angelegt. Gib ihr vor der Schleife einen Startwert.
Schritt 4 von 6 — Vorhersagen
Prüfe dein Verständnis
Was ist die Ausgabe dieser Schleife?
for i in range(1, 5):
print(i, end=" ")- A1 2 3 4 5
- B1 2 3
- C0 1 2 3 4
- D1 2 3 4
Das dritte Argument legt die Schrittweite fest. Was ist die Ausgabe?
for i in range(0, 10, 3):
print(i, end=" ")- A3 6 9
- B0 3 6 9
- C0 1 2 3 4 5 6 7 8 9
- D0 3 6 9 12
Die Absicht war die Summe von 1 bis 10, also 55. Das Programm gibt aber 45 aus. Warum?
total = 0
for number in range(1, 10):
total = total + number
print("Sum of 1 to 10:", total)- A`total` wird außerhalb der Schleife initialisiert, obwohl es innerhalb stehen müsste
- BMit einer `while`-Schleife statt `for` käme das richtige Ergebnis heraus
- CEs müsste `total + i` statt `total + number` heißen
- D`range(1, 10)` endet bei `9` und lässt `10` weg — es müsste `range(1, 11)` sein
Zum Antworten brauchst du ein Konto
Melde dich an, um deine Antworten zu prüfen
Die Fragen stehen oben, und sie im Kopf durchzuarbeiten ist der wichtige Teil. Melde dich an, um die Antworten, die Erklärungen und die dreistufigen Hinweise zu sehen.
Jetzt bist du dran
Schreib eine Datei stars.py, die eine Zahl entgegennimmt und ein Dreieck ausgibt. Bei 5:
*
**
***
****
*****Dann füg diese drei Dinge hinzu:
- Gib unten die Gesamtzahl der Sterne aus (15 bei einer Eingabe von 5)
- Gib das Dreieck zusätzlich auf dem Kopf aus — oben fünf, unten einer
- Gib eine Version aus, die die Zeilen mit geraden Nummern überspringt (verwende
continue)
Für den ersten Punkt gibt es eine einfache Probe: Rechne die Summe von 1 bis 5 von Hand aus und prüf, ob dein Programm dasselbe sagt. Und erinnerst du dich an "*" * i? Für eine Zeile aus Sternen brauchst du keine Schleife innerhalb der Schleife.
Schritt 6 von 6
Herausforderung — das Kapitel-Quiz
Zehn Fragen von leicht bis schwer. Die letzten sind absichtlich knifflig.
Melde dich an, um das Quiz zu machen