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.

Side-by-side flowcharts. while: test the condition, run the body if true, repeat. for: take the next item from the iterable, run the body, repeat until exhausted.

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.