Quando un ciclo deve ignorare alcuni elementi senza interrompere tutto il programma, l’istruzione continue di Python è spesso la soluzione più pulita. In questa guida mostro come funziona nei cicli for e while, come usarla per filtrare dati e record provenienti da un database e quali errori evitare per non creare cicli infiniti o logiche difficili da leggere.
La regola essenziale per usare continue senza errori
- Salta l’iterazione corrente e passa a quella successiva del ciclo.
- Funziona soltanto dentro un ciclo for o while.
- È utile per ignorare dati non validi, vuoti o non pertinenti.
- Non termina il ciclo: per uscire completamente si usa break.
- In un ciclo
whilebisogna aggiornare correttamente la condizione per evitare loop infiniti.
Che cosa fa davvero continue in Python
L’istruzione continue interrompe soltanto l’iterazione in corso. Il programma salta tutte le istruzioni restanti nel blocco del ciclo e riparte dalla prossima iterazione.
numeri = [1, 2, 3, 4, 5]
for numero in numeri:
if numero % 2 == 0:
continue
print(numero)In questo esempio vengono stampati soltanto 1, 3 e 5. Quando il numero è pari, Python esegue continue e non raggiunge la chiamata a print(). Il ciclo, però, non si chiude: prosegue con l’elemento successivo.
La posizione dell’istruzione è importante. Di solito la inserisco dopo una condizione che identifica i dati da scartare, lasciando il percorso principale del codice più leggibile e meno annidato.
Il comportamento nei cicli for
Nel ciclo for, continue fa avanzare l’iteratore. È particolarmente comodo quando si lavora con liste, file, risultati di query o collezioni di oggetti che non devono essere elaborati tutti nello stesso modo.
nomi = ["Luca", "", "Anna", None, "Marco"]
for nome in nomi:
if not nome:
continue
print(f"Utente: {nome}")Le stringhe vuote e il valore None vengono ignorati. Questa forma è spesso più chiara di una lunga serie di blocchi if indentati, soprattutto quando la parte utile dell’elaborazione è più complessa.
Il comportamento nei cicli while
In un ciclo while, dopo continue Python torna a valutare la condizione del ciclo. Qui si nasconde l’errore più comune: se l’aggiornamento della variabile avviene dopo continue, potrebbe non essere mai eseguito.
numero = 0
while numero < 5:
numero += 1
if numero == 3:
continue
print(numero)Il risultato è 1, 2, 4 e 5. L’incremento è stato messo prima del controllo, quindi il ciclo continua a fare progressi anche quando salta la stampa. È una piccola scelta strutturale che evita molti problemi in produzione.
Come usare continue per filtrare dati in modo pratico
Il caso d’uso più naturale è il filtraggio. Quando ricevo una sequenza con valori incompleti, duplicati o non interessanti, preferisco scartarli subito con una condizione esplicita invece di trascinare quei casi fino alla parte principale dell’elaborazione.
Ignorare valori non validi
valori = ["10", "25", "errore", "", "40"]
totale = 0
for valore in valori:
if not valore.isdigit():
continue
totale += int(valore)
print(totale)Il codice somma soltanto i valori convertibili in numeri e ignora “errore” e la stringa vuota. Naturalmente, isdigit() non gestisce numeri negativi o decimali, quindi in un’applicazione reale sceglierei una conversione protetta da try ed except quando l’input è meno prevedibile.
Saltare record già elaborati
elaborati = {"A102", "A105"}
for record in record_da_processare:
codice = record["codice"]
if codice in elaborati:
continue
processa_record(record)Questa tecnica è utile nei processi batch e nelle sincronizzazioni. Il controllo evita di ripetere un’operazione, ma non sostituisce un meccanismo di idempotenza, cioè una progettazione che produce lo stesso risultato anche se la stessa operazione viene eseguita più volte.
Quando è meglio non usarla
Se le condizioni da saltare diventano numerose, il ciclo può trasformarsi in una sequenza di eccezioni difficile da seguire. In quei casi conviene spostare la validazione in una funzione separata oppure filtrare prima i dati con una comprensione di lista, mantenendo comunque leggibile la regola applicata.
numeri_validi = [
numero for numero in numeri
if numero is not None and numero >= 0
]Io uso continue quando la decisione dipende dal flusso dell’elaborazione. Se invece voglio semplicemente costruire una nuova collezione, un filtro dichiarativo può risultare più compatto e più facile da testare.
Continue, break, pass e return non sono intercambiabili
Queste istruzioni vengono spesso confuse perché modificano il normale flusso del programma, ma hanno effetti molto diversi. Scegliere quella sbagliata può produrre risultati incompleti senza generare alcun errore evidente.
| Istruzione | Effetto | Uso tipico |
|---|---|---|
continue |
Salta l’iterazione corrente | Ignorare un elemento e proseguire |
break |
Termina il ciclo più interno | Fermarsi quando si trova ciò che serve |
pass |
Non esegue alcuna operazione | Lasciare temporaneamente vuoto un blocco |
return |
Esce dalla funzione | Restituire un risultato o interrompere tutta la funzione |
for numero in range(1, 6):
if numero == 2:
continue
if numero == 4:
break
print(numero)Il programma stampa 1 e 3. Il numero 2 viene saltato, mentre il numero 4 interrompe il ciclo prima della stampa. Se si sostituisse continue con break, il ciclo terminerebbe troppo presto.
Il caso dei cicli annidati
In presenza di più cicli, continue agisce sul ciclo più interno. Questo comportamento è corretto, ma può sorprendere quando si pensa di voler saltare l’intero gruppo di elaborazioni esterne.
for cliente in clienti:
for ordine in cliente["ordini"]:
if ordine["stato"] == "annullato":
continue
registra_ordine(ordine)Qui viene ignorato soltanto l’ordine annullato. Il ciclo passa all’ordine successivo dello stesso cliente, senza saltare il cliente nel suo insieme. Quando la logica esterna deve reagire a una condizione interna, spesso è più chiaro usare una variabile di controllo o una funzione dedicata.
Gli errori più comuni con continue
La sintassi è semplice, ma gli errori nascono quasi sempre dal punto in cui l’istruzione viene inserita. Il primo controllo che faccio è seguire mentalmente il percorso di una singola iterazione, inclusi gli aggiornamenti delle variabili.
Dimenticare il codice che viene saltato
for riga in righe:
if riga.strip() == "":
continue
logga_riga(riga)
aggiorna_contatore()Per le righe vuote non viene eseguito neppure aggiorna_contatore(). Se il contatore dovrebbe includere anche i record esclusi, va aggiornato prima del controllo oppure gestito in un punto comune. Continue salta tutto ciò che segue nella stessa iterazione, non soltanto la riga immediatamente successiva.
Creare un ciclo while infinito
indice = 0
while indice < 10:
if dati[indice] is None:
continue
indice += 1Se un elemento è None, l’indice non viene incrementato e il programma resta bloccato sullo stesso valore. Una versione sicura aggiorna sempre lo stato prima di continuare oppure usa un ciclo for quando non serve controllare manualmente l’indice.
for valore in dati:
if valore is None:
continue
elabora(valore)Usare continue dentro try e finally
Python esegue comunque il blocco finally prima di iniziare l’iterazione successiva. Questo è importante quando si chiudono file, si rilasciano risorse o si gestiscono connessioni.
for percorso in percorsi:
file = apri_file(percorso)
try:
if file vuoto:
continue
analizza(file)
finally:
file.close()Anche quando il file è vuoto, la chiusura viene eseguita. Nella pratica preferisco spesso usare un with per la gestione delle risorse, perché riduce il rischio di dimenticare la pulizia, ma il comportamento di finally resta fondamentale da conoscere.
Applicare continue ai risultati di un database
Nei programmi che leggono dati da un database, l’istruzione è utile per ignorare record incompleti senza interrompere l’intero batch. Non dovrebbe però diventare un modo per nascondere errori di qualità dei dati: se molti record vengono scartati, serve almeno un log o un contatore.
cursor.execute("""
SELECT id, email, stato
FROM utenti
""")
scartati = 0
for id_utente, email, stato in cursor:
if not email or stato != "attivo":
scartati += 1
continue
invia_notifica(id_utente, email)
print(f"Record scartati: {scartati}")Il ciclo invia notifiche solo agli utenti attivi con un indirizzo presente. Il contatore rende visibile ciò che altrimenti resterebbe silenzioso, una scelta che considero importante nei processi automatici e nelle attività di manutenzione dati.
Validare prima di scrivere
Un altro scenario frequente riguarda l’inserimento di righe importate da CSV o API. Prima di eseguire una INSERT, posso controllare i campi indispensabili e saltare il record incompleto.
for riga in righe_csv:
codice = riga.get("codice")
quantita = riga.get("quantita")
if not codice or not quantita:
registra_scarto(riga, "Dati mancanti")
continue
cursor.execute(
"INSERT INTO prodotti (codice, quantita) VALUES (?, ?)",
(codice, int(quantita))
)Il controllo riduce gli errori durante l’importazione, ma non sostituisce i vincoli del database, come NOT NULL, UNIQUE e FOREIGN KEY. La validazione nel codice migliora il messaggio all’utente; il database resta l’ultima garanzia di integrità.
Leggi anche: Creare un’app Android con Python - Kivy, SQLite e APK
Continue e transazioni
Saltare una riga non annulla automaticamente le operazioni già eseguite nella transazione. Se un batch deve essere tutto atomico, bisogna decidere cosa fare quando alcuni record non sono validi: scartarli e procedere, oppure interrompere e fare rollback.
Per importazioni grandi, spesso separo i record validi da quelli scartati e salvo un report finale. In questo modo il processo può continuare senza perdere tracciabilità, mentre gli errori vengono corretti in un secondo momento.
Una piccola regola pratica per scrivere cicli migliori
Quando inserisco continue, mi chiedo sempre se la condizione rappresenta davvero un caso da ignorare o se sto soltanto evitando di affrontare un errore. Nel primo caso l’istruzione rende il codice più lineare; nel secondo può nascondere un problema che dovrebbe essere segnalato.
- Usalo per filtrare casi previsti e documentabili.
- Evita di saltare silenziosamente eccezioni o dati inattesi.
- Nel ciclo
while, aggiorna lo stato prima del salto. - Nei cicli annidati, ricorda che agisce soltanto sul livello più interno.
- Per i database, registra almeno il numero o il motivo dei record scartati.
La forza di continue non sta nella complessità, ma nella capacità di separare rapidamente i casi da ignorare dal percorso principale. Usato con una condizione chiara e con un minimo di tracciamento, rende i cicli Python più leggibili, più prevedibili e più adatti alla gestione di dati reali.