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, bis ein Ziel erreicht ist, und die kleinste Zahl finden, die eine 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: eine Schleife, die ihren Körper wiederholt, solange eine bestimmte Bedingung wahr ist. Anders als bei der for-Schleife müssen Sie nicht zum Voraus wissen, wie viele Wiederholungen nötig sind — die Schleife läuft einfach, bis die Bedingung kippt.

🌙 Wie oft müssen Sie Papier falten, bis es zum Mond reicht?

Ein Blatt Papier ist etwa 0.1 mm dick. Falten Sie es einmal, ist es doppelt so dick. Nochmals falten: wieder doppelt. Und wieder. Der Mond ist rund 384'400 km entfernt.

Schätzen Sie zuerst — ohne zu rechnen!

Wie oft müssten Sie ein Blatt Papier falten, bis der Stapel den Mond erreicht?

Das Spannende: Wir wissen die Antwort vorher nicht. Genau dafür ist die while-Schleife gemacht. Wir verdoppeln die Dicke einfach so lange, bis sie den Mond erreicht — und zählen dabei mit:

PythonLoading editor…
dicke = 0.1                 # Dicke in Millimeter
mond  = 384_400_000_000     # Distanz zum Mond in Millimeter (384'400 km)
faltungen = 0

while Bedingung:
    # Ihr Code

print("Nötige Faltungen:", faltungen)
print("Dicke danach:", round(dicke / 1_000_000), "km")

42 Faltungen — mehr braucht es nicht. Das ist die Wucht des Verdoppelns (exponentielles Wachstum). Und es ist das perfekte while-Beispiel: Mit einer for-Schleife könnten Sie das kaum sinnvoll schreiben, weil Sie die 42 vorher gar nicht kennen. Die while-Schleife läuft einfach, bis das Ziel erreicht ist.

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. Hier ist i:", i)

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 die kleinste Zahl zu finden

Erinnern Sie sich an die etwas trockene Aufgabe aus der letzten Lektion? Wir suchten 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

Mit der for-Schleife mussten wir eine künstliche Obergrenze (10_000_000) festlegen — obwohl wir gar nicht wussten, ob unsere Zahl da überhaupt drin liegt:

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

Genau dieselbe Schwäche wie beim Papierfalten: Wir kennen die Antwort vorher nicht. 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("Erste Zahl:", i)

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("Erste Zahl:", i)

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.

Übungen

Jetzt sind Sie dran. Die Aufgaben sind nach Schwierigkeit geordnet — fangen Sie oben an und arbeiten Sie sich nach unten. Bei den meisten prüft der Knopf Check automatisch, ob Ihre Lösung stimmt.

🌞 Papier falten — jetzt als Funktion

Erinnern Sie sich an das Papier vom Anfang? Verpacken Sie die Idee in eine Funktion faltungen_bis(distanz_mm), die zurückgibt, wie viele Faltungen nötig sind, bis ein 0.1 mm dickes Blatt die gegebene Distanz erreicht. Testen Sie damit gleich Mond und Sonne.

PythonLoading editor…
def faltungen_bis(distanz_mm):
    dicke = 0.1            # Dicke eines Blatts in Millimeter
    faltungen = 0
    # Verdoppeln Sie die Dicke, solange sie kleiner als distanz_mm ist,
    # und zählen Sie dabei die Faltungen.

    return faltungen

MOND  = 384_400_000_000        # 384'400 km in mm
SONNE = 149_600_000_000_000    # 149,6 Mio. km in mm
print("Bis zum Mond:", faltungen_bis(MOND), "Faltungen")
print("Bis zur Sonne:", faltungen_bis(SONNE), "Faltungen")
Mögliche Lösung
def faltungen_bis(distanz_mm):
    dicke = 0.1
    faltungen = 0
    while dicke < distanz_mm:
        dicke = dicke * 2
        faltungen += 1
    return faltungen

Wann verdoppelt sich dein Geld?

Sie legen 1 Franken an und bekommen jedes Jahr einen festen Zinssatz (z.B. 7 %). Nach wie vielen ganzen Jahren hat sich Ihr Geld zum ersten Mal verdoppelt? Schreiben Sie jahre_bis_verdoppelt(prozent). Pro Jahr gilt: geld = geld * (1 + prozent / 100).

PythonLoading editor…
def jahre_bis_verdoppelt(prozent):

    pass

print(jahre_bis_verdoppelt(7))   # 11
Mögliche Lösung
def jahre_bis_verdoppelt(prozent):
    geld = 1.0
    jahre = 0
    while geld < 2:
        geld = geld * (1 + prozent / 100)
        jahre += 1
    return jahre

Anzahl Stellen einer Zahl

Schreiben Sie anzahl_stellen(n), das zählt, wie viele Ziffern eine positive ganze Zahl hat — ohne die Zahl in einen String umzuwandeln. Trick: Teilen Sie n wiederholt ganzzahlig durch 10 (n = n // 10) und zählen Sie, wie oft das geht, bis n auf 0 schrumpft.

PythonLoading editor…
def anzahl_stellen(n):

    pass

print(anzahl_stellen(7))      # 1
print(anzahl_stellen(2025))   # 4
Mögliche Lösung
def anzahl_stellen(n):
    stellen = 0
    while n > 0:
        n = n // 10      # letzte Ziffer abschneiden
        stellen += 1
    return stellen

Quersumme

Die Quersumme ist die Summe aller Ziffern einer Zahl (z.B. 12341+2+3+4=101234 \rightarrow 1+2+3+4 = 10). Sie steckt in vielen Prüfziffern, etwa bei Barcodes. Schreiben Sie quersumme(n). Trick: n % 10 liefert die letzte Ziffer, n // 10 schneidet sie weg.

PythonLoading editor…
def quersumme(n):

    pass

print(quersumme(1234))   # 10
Mögliche Lösung
def quersumme(n):
    summe = 0
    while n > 0:
        summe += n % 10     # letzte Ziffer dazuzählen
        n = n // 10         # letzte Ziffer wegschneiden
    return summe

Kleinste Zweierpotenz

Computer rechnen gerne in Zweierpotenzen (1, 2, 4, 8, 16, …). Schreiben Sie kleinste_zweierpotenz(n), das die kleinste Zweierpotenz zurückgibt, die mindestens so gross wie n ist. Starten Sie bei p = 1 und verdoppeln Sie, solange p noch kleiner als n ist.

PythonLoading editor…
def kleinste_zweierpotenz(n):

    pass

print(kleinste_zweierpotenz(17))   # 32
Mögliche Lösung
def kleinste_zweierpotenz(n):
    p = 1
    while p < n:
        p = p * 2
    return p

Grösster gemeinsamer Teiler (Euklid)

Ein über 2000 Jahre alter Algorithmus: Der grösste gemeinsame Teiler zweier Zahlen lässt sich finden, indem man wiederholt die grössere durch die kleinere teilt und mit dem Rest weiterrechnet — solange der Rest nicht 0 ist. Schreiben Sie euklid_ggt(a, b).

Tipp: In jedem Schritt wird aus (a, b) neu (b, a % b). Sobald b gleich 0 ist, steht das Ergebnis in a.

PythonLoading editor…
def euklid_ggt(a, b):

    pass

print(euklid_ggt(48, 36))   # 12
Mögliche Lösung
def euklid_ggt(a, b):
    while b != 0:
        a, b = b, a % b
    return a

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.

Bug-Hunt: Die Fakultät

Die Fakultät n!n! ist das Produkt 123n1 \cdot 2 \cdot 3 \cdots n (z.B. 5!=1205! = 120). Diese Funktion sollte das berechnen, liefert für 5 aber nur 24 statt 120. Finden und korrigieren Sie den Fehler.

Tipp: Klassischer Off-by-one. Bis zu welchem Wert läuft die Schleife wirklich?

PythonLoading editor…
def fakultaet(n):
    ergebnis = 1
    i = 1
    while i < n:
        ergebnis *= i
        i += 1
    return ergebnis

print("5! =", fakultaet(5))   # Sollte 120 sein, ist aber 24
Mögliche Lösung
def fakultaet(n):
    ergebnis = 1
    i = 1
    while i <= n:        # `<=` statt `<` — sonst fehlt der letzte Faktor n
        ergebnis *= i
        i += 1
    return ergebnis

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.

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 (wie beim Papierfalten bis zum Mond).

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).