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.