Schleifen
Kurz gesagt: Eine Schleife wiederholt ein Stück Code, so lange es nötig ist: for mit range geht eine Reihe von Zahlen durch, while wiederholt, solange eine Bedingung wahr ist, und break beendet die Schleife.
Problem
Wie viel sparst du?
Du beschließt zu sparen: Im ersten Monat legst du 10 € zur Seite, im zweiten 20 €, im dritten 30 € und so weiter, jedes Mal 10 € mehr. Wie viel hast du nach 4 Monaten?
total = 0total += 1 * 10total += 2 * 10total += 3 * 10total += 4 * 10print(total)100Das funktioniert. Aber nach 3 Jahren sind es 36 Zeilen, fast alle gleich. Und wenn die Zahl der Monate über die Tastatur eingegeben wird, weißt du gar nicht, wie viele Zeilen du schreiben sollst. Du brauchst eine Möglichkeit zu sagen: „Wiederhole das so oft.“
Die Idee
for: für jede Zahl wiederholen
Ein Stück Code, das sich wiederholt, heißt Schleife. Die Schleife, die du am häufigsten brauchst, ist for. Hier sind die Zahlen von 1 bis 10:
for i in range(1, 11): print(i)12345678910for i in range(1, 11): bedeutet „für jedes i aus den Zahlen, die range liefert“. i ist der Zähler: In jedem Durchlauf bekommt er die nächste Zahl. range hat drei Teile, getrennt durch Kommas:
- Start:
1. Die erste Zahl. Fehlt sie wie inrange(10), ist der Start 0. - Ende:
11. Das Ende ist nicht dabei: Die letzte Zahl ist 10. Deshalb gehtrange(1, 11)von 1 bis 10. - Schritt: wie viel jedes Mal dazukommt. Fehlt er, ist er 1.
range(3, 0, -1)zählt rückwärts: 3, 2, 1.
Der Rumpf ist das, was nach dem Doppelpunkt um 4 Leerzeichen eingerückt ist, genau wie bei if.
Jede Ausführung des Rumpfs heißt Iteration oder kurz Durchlauf.
Genauer, für Neugierige
- Der Schritt kann sein, was du brauchst: jede zweite Zahl, rückwärts. Und
range(10)zählt von 0 bis 9: immer noch 10 Durchläufe. Warum man ab 0 zählt, wird in der Lektion über Listen klar.
for i in range(1, 11, 2): print(i, end=" ")print()for i in range(10, 0, -1): print(i, end=" ")print()for i in range(10): print(i, end=" ")print()1 3 5 7 910 9 8 7 6 5 4 3 2 10 1 2 3 4 5 6 7 8 9- In Python gibt es den Zähler auch nach der Schleife noch, mit seinem letzten Wert. In Java, C# und JavaScript ist er nach der Schleife weg.
for i in range(1, 4): print(i)print("Nach der Schleife ist i", i)123Nach der Schleife ist i 3- Python hat kein
formit Bedingung und Schritt wiefor (int i = 1; i <= 10; i++)in Java. Wenn du „solange etwas wahr ist“ brauchst, gibt eswhile(kommt gleich).
Sieh es dir an
Durchlauf für Durchlauf
Das sind die Ersparnisse von der ersten Karte, mit einer Schleife. Sieh zu, wie sich month und total ändern.
total = 0for month in range(1, 5): total += month * 10print(total) # 100Schritt für Schritt, in Worten
- total beginnt bei 0.
- month = 1, die erste Zahl aus range(1, 5). Es geht in den Rumpf.
- Durchlauf 1: total += 1 * 10, total wird 10.
- month wird 2, die nächste Zahl aus range. Noch ein Durchlauf, total wird 30.
- month 3: total wird 60.
- month 4: total wird 100.
- range(1, 5) hat keine Zahlen mehr: Das Ende 5 ist nicht dabei. Die Schleife endet, und month bleibt 4.
- Nach der Schleife ist total 100.
Der Rumpf ist eine Zeile und steht nur einmal da. Für 36 Monate änderst du nur 5 in 37. Du kannst dort sogar eine Variable einsetzen, die von der Tastatur gelesen wurde.
Probier es aus
Rückwärts zählen
Was gibt das Programm aus?
for sec in range(3, 0, -1): print(sec)print("Start!")range(3, 0, -1) zählt rückwärts: 3, 2, 1. Das Ende 0 ist nicht dabei, deshalb wird 0 nicht ausgegeben. Die Zeile nach der Schleife ist nicht eingerückt. Deshalb läuft sie am Ende, einmal.Die Idee
while: bis das Ende kommt
Manchmal weißt du vorher nicht, wie viele Durchläufe es gibt. Die Kasse liest Preise, bis die Kassiererin 0 eingibt, und nennt dann die Summe. Hier passt for nicht. Es passt while: es wiederholt, solange die Bedingung wahr ist.
total = 0price = int(input())while price != 0: total += price price = int(input())print(f"Gesamt: {total} €")12470Gesamt: 23 €Der erste Preis wird vor der Schleife gelesen, damit die Bedingung etwas zu prüfen hat. Der nächste wird am Ende des Rumpfs gelesen. Ist die erste Zahl 0, läuft der Rumpf kein einziges Mal.
Manchmal muss der Rumpf mindestens einmal laufen, und die Bedingung wird erst nach dem Durchlauf geprüft. Zum Beispiel bei einer Frage, die sich wiederholt, bis die Antwort passt. Java, C# und JavaScript haben dafür do-while. Python hat das nicht. Du schreibst while True:, eine Schleife, deren Bedingung immer wahr ist, und darin ein break, das sie beendet, sobald die Antwort passt (mehr zu break gleich):
while True: print("Wie viele Tickets (1 bis 10)?") count = int(input()) if 1 <= count <= 10: breakprint(f"Reservierte Tickets: {count}")0153Wie viele Tickets (1 bis 10)?Wie viele Tickets (1 bis 10)?Wie viele Tickets (1 bis 10)?Reservierte Tickets: 3Genauer, für Neugierige
- Wenn die Bedingung nie falsch wird, endet die Schleife nie. Das ist eine Endlosschleife: Das Programm „hängt“, und du musst es von Hand stoppen. Die häufigste Ursache ist eine vergessene Änderung der Variable in der Bedingung, zum Beispiel ein fehlendes
price = …am Ende des Rumpfs. -
while True:ohnebreakdarin ist eine Endlosschleife. Achte darauf, dass es einen Weg zumbreakgibt. - Jedes for lässt sich als while schreiben. Du nimmst die Variante, die sich klarer liest:
forfür eine bekannte Zahl von Durchläufen,whilefür „bis etwas passiert“.
Probier es aus
Finde den Fehler
Das Programm soll die Zahlen von 1 bis 5 addieren: 1 + 2 + 3 + 4 + 5 = 15. Es gibt 10 aus. In welcher Zeile ist der Fehler?
Wähle die Zeile mit dem Fehler.
Das Ende von range ist nicht dabei: range(1, n) ist 1, 2, 3, 4, und 5 wird nicht addiert: 1 + 2 + 3 + 4 = 10. Richtig ist range(1, n + 1).
So ein Fehler mit einem Durchlauf zu viel oder zu wenig ist der häufigste bei Schleifen. Ein „Schreibtischtest“ findet ihn: Schreib für jeden Durchlauf i und total auf ein Blatt Papier.
Die Summe steht in total, nicht in sum: In Python ist sum der Name einer eingebauten Funktion, und du solltest ihn besser nicht belegen.
Die Idee
break und continue
Zwei Wörter ändern den üblichen Ablauf einer Schleife.
continue überspringt den Rest des aktuellen Durchlaufs und geht zum nächsten. Du listest Termine von 9 bis 17 Uhr auf, aber um 13 Uhr ist Mittagspause:
for hour in range(9, 18): if hour == 13: continue print(f"{hour}:00")9:0010:0011:0012:0014:0015:0016:0017:00break beendet die ganze Schleife sofort. Du suchst die erste Zahl, durch die 91 teilbar ist. Sobald du sie gefunden hast, hat Weitersuchen keinen Sinn:
n = 91for d in range(2, n): if n % d == 0: print(f"{n} ist durch {d} teilbar") break91 ist durch 7 teilbarGenauer, für Neugierige
breakbeendet nur die Schleife, in der es steht. Steht es in einer verschachtelten Schleife (nächste Karte), läuft die äußere weiter.- while True: mit einem break darin kennst du schon: eine Schleife, die nicht durch ihre Bedingung endet, sondern durch ein break an der richtigen Stelle.
Die Idee
Eine Schleife in einer Schleife
Der Kinosaal hat 3 Reihen mit je 4 Plätzen. Du willst jeden Platz ausgeben. Für jede Reihe gehst du alle Plätze darin durch:
for row in range(1, 4): for seat in range(1, 5): print(f"[{row}-{seat}]", end="") print()[1-1][1-2][1-3][1-4][2-1][2-2][2-3][2-4][3-1][3-2][3-3][3-4]Das nennt man verschachtelte Schleifen. Die innere Schleife läuft bei jedem Durchlauf der äußeren komplett durch: 3 Reihen · 4 Plätze = 12 Ausgaben. end="" sagt print, dass es nicht in eine neue Zeile springen soll. So bleiben die Plätze in einer Zeile. Das leere print() nach der inneren Schleife springt in eine neue Zeile.
Probier es aus
Treppe
In der ersten Zeile soll ein Stern stehen, in der zweiten zwei, in der vierten vier. Was gehört in die Lücke?
for row in range(1, 5):
for star in range():
print("*", end="")
print()Die innere Schleife muss so oft laufen, wie die Nummer der Zeile ist. Ihre Grenze ist also row, der Zähler der äußeren Schleife.
Die Idee
Zufallszahlen für Spiele
Ein Würfelspiel braucht eine Zahl, die das Programm vorher nicht kennt. random liefert sie dir:
import random
dice = random.randint(1, 6)print(f"Gewürfelt: {dice}")random ist ein Modul: fertiger Code, der mit Python kommt. Du holst ihn mit import random ganz oben in der Datei herein, genau wie math.
random.randint(1, 6) liefert eine ganze Zahl von 1 bis 6. Achtung: Hier sind beide Grenzen dabei, anders als bei range.
Jeder Start liefert eine andere Zahl, deshalb gibt es hier keine Ausgabe. Und hier ist eine Schleife, die würfelt, bis eine Sechs fällt:
import random
rolls = 0while True: dice = random.randint(1, 6) rolls += 1 if dice == 6: breakprint(f"Sechs nach {rolls} Würfen")Genauer, für Neugierige
- Wenn du mit
random.seed(42)einen Startwert setzt, liefert jeder Start dieselbe Folge. Das hilft beim Testen. random.random()liefert eine Kommazahl von 0 bis 1 (ohne 1), wieMath.random()in JavaScript.
- Die Zahlen sind nicht wirklich zufällig: Sie werden mit einer Formel berechnet. Für Spiele reichen sie, für Passwörter und Sicherheit nicht.
Übung
Aufgaben zu Schleifen
Löse die Aufgaben in deinem Editor. Zu jeder gibt es eine Beispiel-Eingabe und -Ausgabe, mit der du deine vergleichen kannst. Die Zahl liest du genauso ein wie in der Lektion „Eingabe und Ausgabe“.
1. Einmaleins. Lies eine Zahl ein und gib ihre Produkte mit den Zahlen von 1 bis 10 aus.
77 x 1 = 77 x 2 = 147 x 3 = 217 x 4 = 287 x 5 = 357 x 6 = 427 x 7 = 497 x 8 = 567 x 9 = 637 x 10 = 702. Primzahl. Eine Zahl ist eine Primzahl, wenn sie nur durch 1 und durch sich selbst teilbar ist: 2, 3, 5, 7, 11… Lies eine Zahl ein und gib aus, ob sie eine Primzahl ist. Tipp: Probiere die Teiler ab 2 aufwärts und hör beim ersten mit break auf.
9191 ist keine PrimzahlFür 11 ist die Ausgabe „11 ist eine Primzahl“.
3. Die Ziffern einer Zahl. Lies eine positive ganze Zahl ein. Gib sie rückwärts aus und dazu die Summe ihrer Ziffern. Tipp: n % 10 ist die letzte Ziffer, und n // 10 entfernt die letzte Ziffer. Wiederhole das, bis die Zahl 0 wird.
2024Umgekehrt: 4202Quersumme: 84. Zahlenraten. Der Computer „denkt sich“ eine Zahl von 1 bis 100 aus, und du suchst sie. Nach jedem Versuch sagt das Programm „Die Zahl ist kleiner.“ oder „Die Zahl ist größer.“ und am Ende, wie viele Versuche du gebraucht hast. Schreib es zuerst mit der geheimen Zahl 37, damit du es mit dem Beispiel vergleichen kannst:
502537Die Zahl ist kleiner.Die Zahl ist größer.Richtig! Du hast 3 Versuche gebraucht.Wenn es funktioniert, ersetze 37 durch eine Zufallszahl von 1 bis 100. Jetzt kennst nicht einmal du die Antwort.
Weitere Aufgaben
- Von 1 bis N. Lies N ein und gib die Zahlen von 1 bis N in einer Zeile aus. Für 5:
1 2 3 4 5. - Fakultät. N! = 1 · 2 · 3 · … · N. Für 5: 120. In Python hat eine ganze Zahl keine obere Grenze: 20! ist 2432902008176640000, und 30! wird genauso exakt berechnet.
- Primzahlen bis N. Gib alle Primzahlen bis N aus. Für 20:
2 3 5 7 11 13 17 19. Die Prüfung aus Aufgabe 2 kommt in eine Schleife über die Zahlen: verschachtelte Schleifen. - Fibonacci. Jede Zahl ist die Summe der beiden davor: 0, 1, 1, 2, 3, 5, 8… Lies N ein und gib die ersten N Zahlen aus. Für 10:
0 1 1 2 3 5 8 13 21 34. - Quadrat aus Sternen. Lies N ein und gib ein Quadrat N × N aus. Für 3:
* * ** * ** * *- Dreieck aus Sternen. Dasselbe, aber jede Zeile hat so viele Sterne wie ihre Nummer. Für 3:
** ** * *- Münzwurf. Lies N ein, wirf N-mal eine Münze mit einer Zufallszahl (0 ist Kopf, 1 ist Zahl) und gib aus, wie oft jede Seite gefallen ist. Je größer N ist, desto näher kommen beide Zahlen an N / 2.
- Schere, Stein, Papier. Ein Spieler gegen den Computer. Der Spieler gibt seine Wahl ein, der Computer wählt zufällig, und das Programm sagt, wer gewinnt. Mit while True und break fragt es „Noch ein Spiel? (ja/nein)“ und gibt am Ende den Spielstand aus.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Variablen und Typen · Eingabe und Ausgabe · Operatoren und Arithmetik · Bedingungen
- Geht weiter in: Listen · Zweidimensionale Arrays · Strings: mit Text arbeiten · Funktionen
- Aufgaben zum Thema: Sprachgrundlagen