2.12. Schleifen

Eine Schleife führt denselben Codeblock wiederholt aus. Python hat zwei Formen: while, das weiterläuft, solange eine Bedingung wahr bleibt, und for, das die Elemente einer Sequenz durchläuft.

Nebeneinanderstehende Flussdiagramme. while: Bedingung prüfen, den Körper ausführen, falls wahr, wiederholen. for: das nächste Element aus dem Iterierbaren nehmen, den Körper ausführen, wiederholen, bis es erschöpft ist.

while prüft fortlaufend eine Bedingung; for durchläuft eine Sequenz, bis sie erschöpft ist.

2.12.1. while-Schleifen

Eine while-Schleife prüft ihre Bedingung vor jeder Iteration und führt den Körper aus, bis die Prüfung falsch wird:

count = 0
while count < 5:
    print(count)
    count += 1

Ausgabe:

0
1
2
3
4

Wenn die Bedingung am Anfang wahr ist und nie falsch wird, läuft die Schleife endlos. while True: ist das übliche Idiom für eine Hauptschleife, die explizit mit break verlassen wird:

while True:
    step()
    if done():
        break

2.12.2. for-Schleifen

Eine for-Schleife durchläuft die Elemente eines Iterierbaren – eine Liste, ein Tupel, ein String, Bytes, ein Dict oder alles andere, das Iteration unterstützt:

for fruit in ["apple", "banana", "cherry"]:
    print(fruit)

Ausgabe:

apple
banana
cherry

Dieselbe Form funktioniert bei einem String, wobei jedes Element ein String mit einem Zeichen ist:

for letter in "OpenMV":
    print(letter)

Ausgabe:

O
p
e
n
M
V

Das direkte Iterieren über ein Dict liefert seine Schlüssel in Einfügereihenfolge:

for key in {"a": 1, "b": 2}:
    print(key)

Ausgabe:

a
b

Bei jedem Durchlauf wird die Schleifenvariable (fruit, letter, key) an das nächste Element gebunden. Nach dem Ende der Schleife behält die Variable den Wert aus der letzten Iteration.

2.12.3. range

Für Schleifen über einen numerischen Bereich verwenden Sie range():

  • range(stop) – 0, 1, …, stop - 1.

  • range(start, stop) – start, start + 1, …, stop - 1.

  • range(start, stop, step) – mit einer benutzerdefinierten Schrittweite (negative Werte zählen abwärts).

for i in range(5):           # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 8, 2):     # 2, 4, 6
    print(i)

for i in range(10, 0, -1):   # 10, 9, ..., 1
    print(i)

range() erzeugt Werte träge (lazy) – es baut keine Liste im Speicher auf. Um eine tatsächliche list zu erhalten, umschließen Sie es: list(range(10)).

2.12.4. enumerate

Wenn die Schleife sowohl den Index als auch das Element benötigt, liefert enumerate() (index, item)-Paare:

for i, name in enumerate(["a", "b", "c"]):
    print(i, name)
# 0 a
# 1 b
# 2 c

Lassen Sie den Index bei einem anderen Wert als null beginnen, indem Sie ein zweites Argument übergeben: enumerate(items, start=1).

2.12.5. zip

Um zwei (oder mehr) Iterierbare im Gleichschritt zu durchlaufen, verwenden Sie zip(). Es liefert ein Tupel pro Position und hält beim kürzesten Eingang an:

names  = ["alice", "bob", "carol"]
scores = [88, 92, 70]

for name, score in zip(names, scores):
    print(name, score)

Ausgabe:

alice 88
bob 92
carol 70

2.12.6. Zuweisung in einem Ausdruck mit :=

Der Walross-Operator := ist eine Zuweisung, die zugleich ein Ausdruck ist. Er bindet einen Namen und ergibt gleichzeitig denselben Wert. In einer while-Schleife fasst dies das häufige Muster „lesen, prüfen, Körper“ in einer Zeile zusammen:

# without walrus
value = next_value()
while value is not None:
    process(value)
    value = next_value()

# with walrus
while (value := next_value()) is not None:
    process(value)

Die beiden Formen tun dasselbe. Greifen Sie zu :=, wenn die Verdopplung der Zuweisung der Lesbarkeit wirklich schadet; greifen Sie nicht dazu, nur um clever zu sein. Die Klammern sind an den meisten Stellen erforderlich, um den Ausdruck eindeutig zu halten.