2.13. Lusbesturing¶
Twee sleutelwoorden veranderen hoe een lus verloopt:
break– verlaat de lus onmiddellijk.continue– sla de rest van de huidige iteratie over en begin de volgende.
Beide gelden voor de binnenste lus waarin ze voorkomen.
2.13.1. break¶
Gebruik break om een lus te stoppen zodra aan een voorwaarde is voldaan. Het klassieke patroon “zoeken en stoppen”:
found = None
for item in items:
if matches(item):
found = item
break
if found is not None:
print("found:", found)
In een while True:-lus is break de manier waarop de lus eindigt:
while True:
line = next_line()
if line == "quit":
break
process(line)
2.13.2. continue¶
Gebruik continue om de rest van de body over te slaan en naar de volgende iteratie te springen. Handig om items binnen een lus te filteren:
for n in numbers:
if n < 0:
continue # skip negatives
print(n)
Hetzelfde effect kun je schrijven als een if-blok rond de rest van de body. continue is soms duidelijker wanneer de overslaan-voorwaarde gemakkelijker vooraf te formuleren is dan de behoud-voorwaarde.
Binnen een lus vervult continue dezelfde rol als een vroege return in een functie: sla de gevallen die je niet afhandelt over en houd het hoofdwerk vlak op de buitenste inspringing. De filter-en-verwerk-lus is de canonieke vorm:
for item in items:
if item is None:
continue
if not item.is_valid():
continue
process(item)
De ingesprongen regel process(item) is het eigenlijke werk; elke bewaker erboven beschrijft precies welke items worden overgeslagen.
2.13.3. else op een lus¶
Zowel for als while accepteren een optioneel else-blok. Het wordt uitgevoerd wanneer de lus voltooit zonder een break te raken. Het meest voorkomende gebruik is een zoeklus die een terugval wil als er niets is gevonden:
for item in items:
if matches(item):
print("found:", item)
break
else:
print("no match")
Als een break afgaat, wordt het else-blok overgeslagen. Lees de constructie als “for X in Y: …; of anders, als we er nooit uitbraken, doe Z.”
2.13.4. Veelvoorkomende luspatronen¶
Een paar patronen duiken vaak op in echte scripts:
Pollen – wacht tot een bepaalde voorwaarde waar wordt voordat je verdergaat. De body gebruikt
pass, Pythons no-op-instructie; elk ingesprongen blok moet ten minste één instructie bevatten, enpassis de manier om “doe hier niets” te zeggen:while not ready(): pass proceed()
Toestandsmachine – een enkele
while True:-lus die kiest wat te doen op basis van een toestandsvariabele. Nuttig wanneer het werk netjes opsplitst in een paar genoemde fasen:state = "header" for line in lines: if state == "header": if line.startswith("---"): state = "body" elif state == "body": print(line)
Accumuleren – bouw een resultaat op terwijl je een reeks doorloopt:
total = 0 for x in samples: total += x mean = total / len(samples)
Veel accumulatielussen hebben een one-liner-equivalent met een ingebouwde functie. Gebruik de ingebouwde functie wanneer er een van toepassing is:
sum()– telt elk item in een iterable op.any()–Trueals minstens één item waarheidsgetrouw is.all()–Truealleen wanneer elk item waarheidsgetrouw is.sorted()– een nieuwe lijst met de items in volgorde.len()– het aantal items (waar de iterable zijn lengte kent).
>>> 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
De ingebouwde versie is korter, duidelijker en meestal sneller dan dezelfde lus met de hand schrijven.