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, epassè 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.any()–Truese almeno un elemento è truthy.all()–Truesolo 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.