Ein frei kopier- und anpassbares Lehrmittel von eduskript.org

Solange-Schleifen: while

Lernziele
  • Sie verstehen, wie Sie mit while eine Schleife erstellen können, die solange läuft, wie eine Bedingung True ist.
  • Sie können mit einer while-Schleife zählen und die kleinste Zahl finden, die eine bestimmte Bedingung erfüllt.
  • Sie können break (bekannt aus der if-Lektion) auch in while-Schleifen einsetzen, um vorzeitig auszusteigen.
  • Sie haben repetiert, wie man mit input() Benutzereingaben abfragen und mit int() in Zahlen umwandeln kann.

Nun schauen wir uns die while-Schleife an. Das ist eine Schleife, die ihren Körper wiederholt, solange eine bestimmte Bedingung wahr ist. Das ist sinnvoll, wenn Sie im Vornherein nicht wissen, wie oft etwas getan werden soll.

Beginnen wir gleich mit dem Beispiel im letzten Teil. Wir suchten da die kleinste Zahl ii, die alle diese Bedingungen erfüllt:

  • imod113=1i \mod{113} = 1
  • imod213=2i \mod{213} = 2
  • imod313=3i \mod{313} = 3

Die Lösung haben wir gefunden, indem wir bei der for-Schleife manuell den Zahlenbereich schrittweise erhöht haben. Das ist natürlich sehr unpraktisch — und genau das löst die while-Schleife!

Syntax

while Bedingung:
    # Code, der ausgeführt wird, solange die Bedingung wahr ist

Zählen mit while

Zur Veranschaulichung beginnen wir mit einem Beispiel, das ähnlich einer for-Schleife von 0 bis 9 zählt.

PythonLoading editor…
i = 0
while i < 10:
    print("Anfang der Iteration:", i)
    i += 1 # Das ist die verkürzte Schreibweise für i = i + 1
    print("Schluss der Iteration:", i)
    print("*************************") # Ein einfacher Trennstrich
print("Ein print-Statement am Schluss, das nicht mehr zur Schleife gehört")

Beachten Sie folgende Aspekte:

  • Für den Codeblock gilt die typische Syntax: Ein Doppelpunkt schliesst den Kopf des Blocks ab, der Einzug links definiert, was zur Schleife gehört.
  • Die Bedingung der while-Schleife wird wie bei if-Statements geschrieben.
  • Die Bedingung wird nur zu Beginn einer Iteration überprüft. Wenn die Bedingung True ist, wird der gesamte Körper der Schleife wiederholt. Das sehen Sie beim letzten "Schluss der Iteration", das ausgeführt wird, obwohl i bereits den Wert 10 hat und die Bedingung nicht mehr erfüllt.

Predict-then-Verify: Off-by-one!

Ein häufiger Fehler bei while-Schleifen ist das sogenannte "Off-by-one"-Problem (um eins daneben). Überlegen Sie kurz, was am Ende dieses Programms ausgegeben wird:

k = 5
while k <= 7:
    k += 1
print("Fertig:", k)

Beispiele

Elegante Lösung, um kleinste Zahl zu finden

Kehren wir damit nochmal zur Aufgabe aus dem letzten Teil zurück. Unsere Lösung war:

for i in range(10000000):
    if i % 113 == 1 and i % 213 == 2 and i % 313 == 3:
        ergebnis = i
        break
print(ergebnis, "restlose Zahl")

Wir mussten dort eine künstliche Obergrenze (10_000_000) festlegen — obwohl wir gar nicht wussten, ob unsere Zahl da überhaupt drin liegt. Mit der while-Schleife geht das eleganter: Wir lassen sie einfach laufen, solange wir die Zahl noch nicht gefunden haben.

PythonLoading editor…
i = 0
while not (i % 113 == 1 and i % 213 == 2 and i % 313 == 3):
    i += 1
print(i, "restlose Zahl")

Die einzelnen Teilbedingungen der while-Schleife könnten Sie auch ausklammern.

# "Solange die gesamte Bedingung nicht erfüllt ist", ist logisch dasselbe wie...
not (i % 113 == 1 and i % 213 == 2 and i % 313 == 3)
# "Solange eine der Bedingungen nicht erfüllt ist"
i % 113 != 1 or i % 213 != 2 or i % 313 != 3

Variante mit break

Erinnern Sie sich an break aus der if-Lektion? Das funktioniert in while-Schleifen genauso. Statt mit der unangenehmen Negation not (...) zu arbeiten, können wir das Programm auch positiv formulieren: Schleife läuft endlos — und sobald die Bedingung erfüllt ist, brechen wir mit break ab.

PythonLoading editor…
i = 0
while True:
    i += 1
    if i % 113 == 1 and i % 213 == 2 and i % 313 == 3:
        break
print(i, "restlose Zahl")

Das ist oft lesbarer als die Negationsvariante — speziell wenn die Bedingung kompliziert ist. Welche Form Sie wählen, ist Geschmackssache — beide funktionieren und liefern dasselbe Ergebnis. Wichtig: Bei while True müssen Sie zwingend dafür sorgen, dass irgendwann ein break greift, sonst läuft die Schleife endlos.

Endlosschleife mit while

Ein Beispiel, wo while True mit break besonders natürlich ist: Eingaben verarbeiten, bis der User aufhören will.

while True:
    eingabe = input("Geben Sie eine Zahl ein (oder 'exit' zum Beenden): ")
    if eingabe == "exit":
        break
    else:
        print("Sie haben die Zahl", eingabe, "eingegeben.")

Hier wäre es umständlich, eine Bedingung wie while eingabe != "exit" zu formulieren — denn eingabe existiert beim Start der Schleife ja noch gar nicht. Mit while True und break löst sich das Problem natürlich auf.

Wann ist eine echte Endlosschleife (ohne break) sinnvoll? Bei echten Computerprogrammen eher selten. Aber bei kleinen Robotern oder Microcontrollern, die immer dasselbe tun sollen, solange sie Strom haben, kann eine Endlosschleife durchaus passen.

Bug-Hunt: Der Summen-Hänger

Hier wollte jemand die Summe aller Zahlen von 1 bis n berechnen. Für n=10 sollte 55 herauskommen, aber das Programm liefert nur 10. Finden und korrigieren Sie den Fehler.

Tipp: Die Schleife läuft korrekt — schauen Sie genau, was im Schleifenkörper mit total passiert.

PythonLoading editor…
def summe_bis(n):
    total = 0
    i = 1
    while i <= n:
        total = i
        i += 1
    return total

print("Summe bis 10:", summe_bis(10))   # Sollte 55 sein, ist aber 10
Mögliche Lösung
def summe_bis(n):
    total = 0
    i = 1
    while i <= n:
        total += i       # `+=` addiert auf, statt zu überschreiben
        i += 1
    return total

Der Fehler war eine vertauschte Operatorwahl. total = i überschreibt total in jedem Durchlauf — am Ende steht dort nur noch der letzte Wert von i. Mit total += i (kurz für total = total + i) wird der aktuelle Wert von i jedes Mal aufaddiert.

Challenge: Collatz-Folge

Die Collatz-Folge ist eines der berühmtesten ungelösten Probleme der Mathematik. Die Regel ist denkbar einfach: Sie starten bei einer beliebigen positiven Zahl n und wiederholen folgende Schritte, bis Sie bei 1 ankommen:

  • Ist n gerade, halbieren Sie es: n = n // 2
  • Ist n ungerade, rechnen Sie: n = 3 * n + 1

Niemand weiss bis heute, ob diese Folge wirklich für jede Startzahl irgendwann bei 1 endet — aber empirisch klappt es bisher immer.

Auto-Grading

Schreiben Sie eine Funktion collatz_schritte(n), die die Anzahl Schritte zurückgibt, die nötig sind, bis aus n eine 1 wird. Die while-Schleife ist hier perfekt: Sie wissen vorher nicht, wie lange es dauert!

PythonLoading editor…
def collatz_schritte(n):
    # Zählen Sie hier die Schritte, bis n auf 1 schrumpft.
    pass

# Ein paar Tests:
print("collatz_schritte(6) =", collatz_schritte(6))    # 8 Schritte: 6→3→10→5→16→8→4→2→1
print("collatz_schritte(27) =", collatz_schritte(27))  # 111 Schritte (berüchtigt lang!)
Mögliche Lösung
def collatz_schritte(n):
    schritte = 0
    while n != 1:
        if n % 2 == 0:
            n = n // 2
        else:
            n = 3 * n + 1
        schritte += 1
    return schritte

Beachten Sie: Die while-Bedingung ist n != 1 — wir laufen, solange wir noch nicht angekommen sind. Sobald n == 1, bricht die Schleife ab und wir geben die gezählten Schritte zurück.

Aufgabe: Ein Ratespiel entwickeln mit while

Im folgenden Beispiel entwickeln wir ein kleines Ratespiel. Der Computer denkt sich eine Zahl zwischen 1 und 100 aus, und der Spieler muss sie erraten. Der Computer gibt dem Spieler Hinweise, ob die geratene Zahl zu hoch oder zu niedrig ist.

Pseudocode

Die Idee etwas genauer in Pseudocode gefasst:

Zufallszahl zwischen 1 und 100 ziehen
Solange die Zahl nicht erraten wurde
    Eingabe abfragen
    Wenn die Zahl zu hoch ist:
        Hinweis geben: "Zu hoch!"
    Wenn die Zahl zu niedrig ist:
        Hinweis geben: "Zu niedrig!"
Hinweis geben: "Gratuliere!"

Zufallszahlen ziehen

Um eine Zufallszahl zu ziehen, verwenden wir die Funktion randint aus dem Modul random. Diese Funktion zieht eine ganze Zahl zwischen zwei Werten (inklusive der beiden Werte). Wir importieren das Modul mit dem Befehl import random.

import random
# Zufallszahl zwischen 1 und 100
zahl = random.randint(1, 100)
print(zahl)

Input abfragen

Um den Spieler nach einer Zahl zu fragen, verwenden wir die Funktion input. Diese Funktion gibt den eingegebenen Text als String zurück. Um ihn in eine Ganzzahl umzuwandeln, verwenden wir die Funktion int.

# Eingabe abfragen
eingabe = input("Gib eine Zahl zwischen 1 und 100 ein: ")
# Eingabe von Zeichenkette/String in Ganzzahl/Integer umwandeln
zahl = int(eingabe)
print(zahl)

Ihre Lösung

PythonLoading editor…
# Ihr Code

Erklärvideo

Mögliche Lösung
import random

# Generiere eine Zufallszahl zwischen 1 und 100
geheimzahl = random.randint(1, 100)

# Variablen für das Spiel initialisieren
versuchsrunde = 0
geratete_zahl = -1

# Begrüssung und Spielerklärung
print("Willkommen zum Zahlenratespiel!")
print("Ich habe mir eine Zahl zwischen 1 und 100 ausgedacht.")

# Solange die Zahl nicht erraten wurde, weiterspielen
while geratete_zahl != geheimzahl:
    eingabe = input("Rate eine Zahl zwischen 1 und 100: ")
    geratete_zahl = int(eingabe)
    versuchsrunde += 1

    # Prüfen, ob die geratene Zahl korrekt ist
    if geratete_zahl < geheimzahl:
        print("Zu niedrig! Versuch es mit einer höheren Zahl.")
    elif geratete_zahl > geheimzahl:
        print("Zu hoch! Versuch es mit einer niedrigeren Zahl.")

# Wenn die Zahl erraten wurde, gratulieren
print("Gratuliere! Du hast die Zahl", geheimzahl, "in", versuchsrunde, "Versuchen erraten!")

Zusammenfassung

Zusammenfassung

while-Schleife

Eine while-Schleife wiederholt ihren Körper, solange eine Bedingung True ist. Im Gegensatz zur for-Schleife müssen Sie nicht im Voraus wissen, wie viele Iterationen nötig sind — perfekt, wenn Sie auf ein Ereignis warten oder so lange suchen, bis Sie etwas finden.

while Bedingung:
    # Code, der wiederholt wird

Drei klassische while-Bugs

  • Vergessenes Update: Wenn keine Variable in der Bedingung verändert wird, läuft die Schleife endlos. Sorgen Sie immer dafür, dass die Bedingung irgendwann False wird.
  • Falsches Update: Wie im Bug-Hunt — total = i statt total += i schreibt jeden Schritt einfach den letzten Wert in die Variable, statt aufzubauen.
  • Off-by-one: Die Bedingung wird vor jedem Durchlauf geprüft, nicht danach. Eine Schleife mit while i <= 7 läuft auch noch, wenn i gleich 7 ist — und erhöht i dann auf 8.

break (Wiederholung aus der if-Lektion)

break funktioniert in while-Schleifen genauso wie in for-Schleifen — sobald break ausgeführt wird, wird die Schleife sofort verlassen. Zwei typische Muster:

# Variante 1: Negation in der Bedingung
while not (i % 113 == 1 and i % 213 == 2 and i % 313 == 3):
    i += 1

# Variante 2: while True + break (oft lesbarer)
while True:
    i += 1
    if i % 113 == 1 and i % 213 == 2 and i % 313 == 3:
        break

Beide Varianten sind korrekt — wählen Sie die, die für Sie und Ihre Mitlesenden klarer ist.

Wann for, wann while?

  • for wenn die Anzahl Iterationen vorher feststeht (eine Liste durchgehen, eine Range zählen).
  • while wenn das Ende von einer Bedingung abhängt (auf etwas warten, bis zu einem Ereignis suchen).