2.13. Controllo del ciclo

Due parole chiave modificano l’esecuzione di un ciclo:

  • break – esce immediatamente dal ciclo.

  • continue – salta il resto dell’iterazione corrente e passa alla successiva.

Entrambe si applicano al ciclo più interno in cui compaiono.

2.13.1. break

Usa break per interrompere un ciclo non appena una condizione è soddisfatta. Il classico schema «cerca e fermati»:

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

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

In un ciclo while True:, break è il modo in cui il ciclo termina:

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

2.13.2. continue

Usa continue per saltare il resto del corpo e passare all’iterazione successiva. Utile per filtrare gli elementi all’interno di un ciclo:

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

Lo stesso effetto può essere scritto come un blocco if attorno al resto del corpo. continue a volte risulta più chiaro quando la condizione di salto è più semplice da esprimere in anticipo rispetto alla condizione di mantenimento.

All’interno di un ciclo, continue svolge lo stesso ruolo di un return anticipato in una funzione: salta i casi che non gestisci e mantiene il lavoro principale allineato all’indentazione esterna. Il ciclo filtra-ed-elabora è la forma canonica:

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

La riga indentata process(item) è il lavoro vero e proprio; ciascuna guardia sopra di essa specifica esattamente quali elementi vengono saltati.

2.13.3. else su un ciclo

Sia for sia while accettano un blocco else opzionale. Viene eseguito quando il ciclo termina senza incontrare un break. L’uso più comune è un ciclo di ricerca che vuole un’alternativa nel caso in cui non venga trovato nulla:

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

Se viene attivato un break, il blocco else viene saltato. Leggi il costrutto come «for X in Y: …; oppure, se non siamo mai usciti, fai Z.»

2.13.4. Schemi di ciclo comuni

Alcuni schemi ricorrono spesso negli script reali:

  • Polling – attendi che una condizione diventi vera prima di proseguire. Il corpo usa pass, l’istruzione no-op di Python; ogni blocco indentato deve contenere almeno un’istruzione, e pass è il modo per dire «non fare nulla qui»:

    while not ready():
        pass
    proceed()
    
  • Macchina a stati – un singolo ciclo while True: che sceglie cosa fare in base a una variabile di stato. Utile quando il lavoro si suddivide nettamente in poche fasi denominate:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Accumulazione – costruisci un risultato mentre percorri una sequenza:

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

    Molti cicli di accumulazione hanno un equivalente di una sola riga che usa una funzione built-in. Ricorri alla funzione built-in quando ne esiste una applicabile:

    • sum() – somma ogni elemento di un iterabile.

    • max() / min() – l’elemento più grande o più piccolo.

    • any()True se almeno un elemento è truthy.

    • all()True solo quando ogni elemento è truthy.

    • sorted() – una nuova lista con gli elementi ordinati.

    • len() – il numero di elementi (quando l’iterabile conosce la propria lunghezza).

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

    La versione built-in è più breve, più chiara e di solito più veloce rispetto a scrivere a mano lo stesso ciclo.