2.13. Loopkontroll

Två nyckelord ändrar hur en loop körs:

  • break – avsluta loopen omedelbart.

  • continue – hoppa över resten av den aktuella iterationen och börja på nästa.

Båda gäller den innersta loop de förekommer inuti.

2.13.1. break

Använd break för att stoppa en loop så snart ett villkor är uppfyllt. Det klassiska mönstret ”sök och stoppa”:

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

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

I en while True:-loop är break sättet loopen avslutas på:

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

2.13.2. continue

Använd continue för att hoppa över resten av kroppen och gå vidare till nästa iteration. Praktiskt för att filtrera bort objekt inuti en loop:

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

Samma effekt kan skrivas som ett if-block runt resten av kroppen. continue är ibland tydligare när villkoret för att hoppa över är lättare att uttrycka i förväg än villkoret för att behålla.

Inuti en loop spelar continue samma roll som ett tidigt return i en funktion: hoppa förbi de fall du inte hanterar och håll huvudarbetet plant på den yttre indenteringen. Filtrera-och-bearbeta-loopen är den kanoniska formen:

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

Den indenterade raden process(item) är det faktiska arbetet; varje vakt ovanför anger exakt vilka objekt som hoppas över.

2.13.3. else på en loop

Både for och while accepterar ett valfritt else-block. Det körs när loopen slutförs utan att träffa på ett break. Den vanligaste användningen är en sökloop som vill ha en reservlösning om inget hittades:

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

Om ett break utlöses hoppas else-blocket över. Läs konstruktionen som ”for X in Y: …; eller annars, om vi aldrig bröt oss ut, gör Z.”

2.13.4. Vanliga loopmönster

Några mönster dyker upp ofta i verkliga skript:

  • Pollning – vänta tills något villkor blir sant innan du går vidare. Kroppen använder pass, Pythons no-op-sats; varje indenterat block måste innehålla minst en sats, och pass är sättet att säga ”gör ingenting här”:

    while not ready():
        pass
    proceed()
    
  • Tillståndsmaskin – en enda while True:-loop som väljer vad som ska göras baserat på en tillståndsvariabel. Användbart när arbetet delas rent upp i några namngivna faser:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Ackumulering – bygg upp ett resultat medan du går igenom en sekvens:

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

    Många ackumuleringsloopar har en enradsekvivalent med en inbyggd funktion. Använd den inbyggda funktionen när någon passar:

    • sum() – adderar varje objekt i en itererbar.

    • max() / min() – det största eller minsta objektet.

    • any()True om minst ett objekt är sant.

    • all()True endast när varje objekt är sant.

    • sorted() – en ny lista med objekten i ordning.

    • len() – antalet objekt (där den itererbara känner till sin längd).

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

    Den inbyggda versionen är kortare, tydligare och vanligtvis snabbare än att skriva samma loop för hand.