2.13. Schleifensteuerung

Zwei Schlüsselwörter verändern den Ablauf einer Schleife:

  • break – verlässt die Schleife sofort.

  • continue – überspringt den Rest der aktuellen Iteration und beginnt die nächste.

Beide wirken sich auf die innerste Schleife aus, in der sie auftreten.

2.13.1. break

Verwenden Sie break, um eine Schleife zu beenden, sobald eine Bedingung erfüllt ist. Das klassische Muster „Suchen und Anhalten“:

found = None
for item in items:
    if matches(item):
        found = item
        break

if found is not None:
    print("found:", found)

In einer while True:-Schleife ist break die Art und Weise, wie die Schleife endet:

while True:
    line = next_line()
    if line == "quit":
        break
    process(line)

2.13.2. continue

Verwenden Sie continue, um den Rest des Schleifenkörpers zu überspringen und zur nächsten Iteration zu springen. Praktisch, um Elemente innerhalb einer Schleife zu filtern:

for n in numbers:
    if n < 0:
        continue            # skip negatives
    print(n)

Derselbe Effekt lässt sich auch als if-Block um den Rest des Schleifenkörpers schreiben. continue ist manchmal klarer, wenn sich die Überspringbedingung leichter im Voraus formulieren lässt als die Behaltbedingung.

Innerhalb einer Schleife spielt continue dieselbe Rolle wie ein frühes return in einer Funktion: Überspringen Sie die Fälle, die Sie nicht behandeln, und halten Sie die eigentliche Arbeit flach auf der äußeren Einrückung. Die Schleife nach dem Muster Filtern-und-Verarbeiten ist die kanonische Form:

for item in items:
    if item is None:
        continue
    if not item.is_valid():
        continue
    process(item)

Die eingerückte Zeile process(item) ist die eigentliche Arbeit; jede Schutzbedingung darüber legt genau fest, welche Elemente übersprungen werden.

2.13.3. else bei einer Schleife

Sowohl for als auch while akzeptieren einen optionalen else-Block. Er wird ausgeführt, wenn die Schleife durchläuft, ohne auf ein break zu treffen. Die häufigste Anwendung ist eine Suchschleife, die einen Ausweichfall benötigt, falls nichts gefunden wurde:

for item in items:
    if matches(item):
        print("found:", item)
        break
else:
    print("no match")

Wenn ein break ausgelöst wird, wird der else-Block übersprungen. Lesen Sie das Konstrukt als „for X in Y: …; oder andernfalls, wenn wir nie ausgebrochen sind, mache Z.“

2.13.4. Häufige Schleifenmuster

Ein paar Muster tauchen in echten Skripten häufig auf:

  • Polling – warten, bis eine Bedingung wahr wird, bevor es weitergeht. Der Schleifenkörper verwendet pass, Pythons Leeranweisung; jeder eingerückte Block muss mindestens eine Anweisung enthalten, und pass ist die Art und Weise, „hier nichts tun“ auszudrücken:

    while not ready():
        pass
    proceed()
    
  • Zustandsmaschine – eine einzelne while True:-Schleife, die anhand einer Zustandsvariablen entscheidet, was zu tun ist. Nützlich, wenn sich die Arbeit sauber in einige benannte Phasen aufteilen lässt:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Akkumulieren – ein Ergebnis aufbauen, während eine Sequenz durchlaufen wird:

    total = 0
    for x in samples:
        total += x
    mean = total / len(samples)
    

    Viele Akkumulationsschleifen haben ein einzeiliges Äquivalent mit einer eingebauten Funktion. Greifen Sie zur eingebauten Funktion, wenn eine passt:

    • sum() – addiert jedes Element in einem Iterierbaren.

    • max() / min() – das größte oder kleinste Element.

    • any()True, wenn mindestens ein Element wahrheitswertig ist.

    • all()True nur, wenn jedes Element wahrheitswertig ist.

    • sorted() – eine neue Liste mit den Elementen in sortierter Reihenfolge.

    • len() – die Anzahl der Elemente (sofern das Iterierbare seine Länge kennt).

    >>> samples = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> sum(samples)
    31
    >>> sum(samples) / len(samples)        # mean
    3.875
    >>> max(samples)
    9
    >>> min(samples)
    1
    >>> sorted(samples)
    [1, 1, 2, 3, 4, 5, 6, 9]
    >>> any([False, False, True])
    True
    >>> all([True, True, False])
    False
    

    Die eingebaute Variante ist kürzer, klarer und in der Regel schneller, als dieselbe Schleife von Hand zu schreiben.