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.