Cicli while — ripetere finché una condizione è vera
Ripetere lo stesso lavoro, come nascono i cicli infiniti e come fermarli, break e continue, e chiedere di nuovo finché l'input non è valido.
Come vuoi imparare?
Il problema che stiamo risolvendo
Nel capitolo precedente abbiamo imparato a intercettare un input sbagliato — quando qualcuno scrive twenty, il programma può rispondere "non è un numero".
Ma cosa fa dopo averlo detto? Si ferma. La persona deve rieseguire tutto il programma da capo. Nessun software serio funziona così: chiede di nuovo, e continua a chiedere finché non riceve una risposta valida.
È a questo che servono i cicli: ripetere lo stesso lavoro più volte, finché serve. Oggi impariamo while, che viene eseguito finché una condizione resta vera.
C'è anche una nuova esperienza che ti aspetta oggi: un programma che non si ferma mai, con il testo che scorre velocissimo nel terminale. Non c'è da preoccuparsi — in questo stesso capitolo imparerai come fermarlo.
Alla fine di questo capitolo sarai in grado di
- Scrivere un ciclo
whilee dire quando si fermerà - Riconoscere perché nascono i cicli infiniti, e fermarne uno con
Ctrl + C - Accumulare una somma o un conteggio dentro un ciclo
- Usare
breakecontinuenei punti giusti - Continuare a chiedere finché l'input non è valido
Prerequisiti: Prendere decisioni — if, elif, else.
Il ciclo più semplice
count = 3
while count > 0:
print(count)
count = count - 1
print("Go")3
2
1
GoLa forma assomiglia a quella di un if — condizione, due punti, blocco indentato. C'è una differenza, ed è tutta la differenza: un if controlla la condizione una volta sola; un while la ricontrolla ogni volta che il blocco finisce.
Cosa ha fatto il programma qui sopra:
countvale3. La condizione3 > 0è vera → il blocco è stato eseguito, ha stampato3, ecountè diventato2- Di nuovo la condizione:
2 > 0è vera → ha stampato2, ecountè diventato1 - Di nuovo:
1 > 0è vera → ha stampato1, ecountè diventato0 - Di nuovo:
0 > 0è falsa → il ciclo è terminato e l'esecuzione è proseguita
Ogni ciclo while funzionante ha tre parti, e servono tutte e tre:
- Un valore iniziale — prima del ciclo (
count = 3) - Una condizione — quando continuare (
count > 0) - Un cambiamento — qualcosa dentro il ciclo che prima o poi renderà falsa la condizione (
count = count - 1)
Cicli infiniti
Vale la pena vedere cosa succede quando manca la terza parte:
count = 3
while count > 0:
print(count)Questo stampa 3 all'infinito. count non cambia mai, quindi count > 0 non diventa mai falsa.
Come fermarlo: premi Ctrl + C nel terminale. Il programma si interrompe subito e mostra qualcosa di simile:
Traceback (most recent call last):
File "D:\python-lab\lesson-10\loop.py", line 4, in <module>
print(count)
KeyboardInterruptLa riga File mostrerà il percorso completo del tuo file, e il numero di riga dipende dal momento preciso in cui hai premuto i tasti. KeyboardInterrupt significa che l'hai fermato tu. Non è un bug nel tuo codice, è una tua decisione.
I cicli infiniti fanno parte dell'apprendimento. Ogni programmatore ne ha scritto uno, e ne scrive ancora. Non c'è nulla da temere — sapere usare Ctrl + C lo riduce a un fastidio minore. Quando scrivi un ciclo, chiediti una sola cosa: "come diventerà falsa questa condizione?" Se non sai rispondere, il ciclo non si fermerà.Accumulare
Il compito più comune per un ciclo è costruire qualcosa man mano — una somma, un conteggio, il valore più grande visto finora:
total = 0
number = 1
while number <= 5:
total = total + number
number = number + 1
print("Sum of 1 to 5:", total)Sum of 1 to 5: 15total si chiama accumulatore — il contenitore in cui raccogli i valori. Nota che parte fuori dal ciclo, da 0. Se lo inizializzassi dentro, verrebbe azzerato a ogni giro, e alla fine resterebbe solo l'ultimo numero.
break — esci subito
break termina il ciclo immediatamente, qualunque cosa dica la condizione:
number = 1
while number <= 100:
if number % 7 == 0:
print("First multiple of 7:", number)
break
number = number + 1First multiple of 7: 7La condizione diceva di arrivare fino a 100, ma il lavoro era finito nel momento in cui è comparso il 7 — quindi non aveva senso fare altri 93 giri.
break rende possibile anche uno schema che si rivela molto utile — scrivere True come condizione e uscire dal punto giusto all'interno:
while True:
answer = input("Type 'quit' to exit: ").strip().lower()
if answer == "quit":
print("Goodbye")
break
print(f"You typed: {answer}")Type 'quit' to exit: hello
You typed: hello
Type 'quit' to exit: QUIT
Goodbyewhile True significa "esegui per sempre", quindi un break dentro è obbligatorio — altrimenti è un ciclo infinito.
continue — salta questo giro
continue non termina il ciclo; salta il resto del blocco e passa direttamente al giro successivo:
number = 0
while number < 10:
number = number + 1
if number % 2 == 0:
continue
print(number)1
3
5
7
9Per ogni numero pari continue è stato eseguito, quindi la print è stata saltata.
Attenzione a come si scrivecontinue. Se la riga che fa avanzare la condizione (number = number + 1) si trova dopo ilcontinue,continuela salta — e il ciclo resta bloccato lì per sempre. Per questo nel codice qui sopra l'incremento viene per primo. Ogni volta che usicontinue, controlla questo ordine.
Infine: chiedere finché l'input non è valido
È la cosa che aspettavamo da due capitoli:
while True:
raw = input("Your age: ").strip()
if raw.isdigit():
age = int(raw)
break
print("Please type a whole number, digits only.")
print(f"Thank you. Age recorded as {age}.")Your age: twenty
Please type a whole number, digits only.
Your age: 22.5
Please type a whole number, digits only.
Your age: 22
Thank you. Age recorded as 22.Questo è lo schema che userai per tutta la vita lavorativa: ciclo infinito, validazione dentro, break quando il valore è valido, messaggio e nuovo giro quando non lo è. Il programma non crolla più davanti a un input sbagliato, e la persona non deve ricominciare da capo.
Un esempio completo
shopping.py:
# Keep taking item prices until the user is done, then summarise
total = 0.0
item_count = 0
print("Enter item prices. Type 'done' to finish.")
while True:
entry = input("Price: ").strip().lower()
if entry == "done":
break
if entry == "":
print(" Nothing typed — try again.")
continue
# Accept only digits and at most one decimal point
if entry.replace(".", "", 1).isdigit():
price = float(entry)
total = total + price
item_count = item_count + 1
print(f" Added {price:.2f}. Running total {total:.2f}")
else:
print(f" '{entry}' is not a price. Try again.")
print()
if item_count == 0:
print("No items were entered.")
else:
average = total / item_count
print(f"Items : {item_count}")
print(f"Total : {total:.2f}")
print(f"Average : {average:.2f}")Enter item prices. Type 'done' to finish.
Price: 120
Added 120.00. Running total 120.00
Price: abc
'abc' is not a price. Try again.
Price: 85.5
Added 85.50. Running total 205.50
Price: done
Items : 2
Total : 205.50
Average : 102.75Tre cose lavorano insieme qui, e tutte e tre sono il materiale di oggi:
break— uscire dal ciclo quando la persona scrivedonecontinue— saltare il resto e chiedere di nuovo quando la riga è vuota- Accumulatori —
totaleitem_countpartono entrambi fuori dal ciclo e crescono dentro
Pensa al motivo per cui quell'ultimo if item_count == 0 serve. Se qualcuno scrive subito done senza inserire nulla, item_count vale 0, e total / item_count farebbe crashare il programma con un ZeroDivisionError. Prima di usare qualsiasi cosa accumulata da un ciclo, fatti sempre questa domanda: "ha accumulato davvero qualcosa?"
Quando qualcosa va storto
Il programma non si ferma, il testo scorre via veloce Premi Ctrl + C. Poi controlla che il corpo del ciclo contenga la riga che fa avanzare la condizione, e che non si trovi dopo un continue.
Il ciclo non viene eseguito affatto La condizione era già falsa. Confronta il valore iniziale con la condizione — while count > 0 partendo da count = 0 non entra mai nel ciclo.
Gira una volta in più o in meno Hai scambiato < con <=. Partendo da n = 1, while n < 5 gira quattro volte (con n pari a 1, 2, 3, 4), e while n <= 5 gira cinque volte. Se cambi il valore iniziale cambia anche il numero di giri — partendo da n = 0, while n < 5 gira cinque volte. Quindi controlla sempre insieme il valore iniziale e la condizione.
IndentationError: expected an indented block after 'while' statement La riga dopo il while non è indentata.
NameError dopo il ciclo — la variabile è sconosciuta La variabile è stata creata solo dentro il ciclo, e se il ciclo non è mai stato eseguito non è stata mai creata. Dai a ogni variabile che ti serve dopo il ciclo un valore iniziale prima del ciclo.
Il totale è sbagliato alla fine del ciclo Controlla se l'accumulatore viene inizializzato dentro il ciclo. La riga total = 0 deve stare fuori.
Passo 4 di 6 — Prevedi
Verifica cosa hai capito
Qual è l'output completo di questo ciclo?
count = 3
while count > 0:
print(count)
count = count - 1
print("Go")- A2 1 0 Go
- B3 2 1 0 Go
- C3 Go
- D3 2 1 Go
Questo programma non si ferma mai. Che cosa manca?
total = 0
number = 1
while number <= 5:
total = total + number
print(total)- AIl `while` dovrebbe essere un `if`
- BNon c'è `number = number + 1` dentro il ciclo, quindi la condizione non diventa mai falsa
- CCambiare `<=` in `<` nella condizione lo fermerebbe
- D`total` non è stato inizializzato dentro il ciclo
Con quel continue al suo posto, che cosa stampa questo ciclo?
number = 0
while number < 5:
number = number + 1
if number == 3:
continue
print(number)- A1 2 4 5
- B1 2 3 4 5
- C1 2 4
- D1 2
Per rispondere serve un account
Accedi per verificare le tue risposte
Le domande sono qui sopra, e ragionarci a mente è la parte che conta. Accedi per vedere le risposte, le spiegazioni e i suggerimenti a tre livelli.
Tocca a te
Scrivi un gioco di indovinelli, guess.py:
- Fissa nel codice un numero segreto, compreso tra 1 e 100
- Chiedi alla persona di indovinare, e a ogni tentativo stampa "higher" o "lower"
- Se indovina, fai i complimenti e esci dal ciclo
- Stampa quanti tentativi ci sono voluti
- Se scrive qualcosa che non è un numero, il programma non deve rompersi — stampa un messaggio e chiedi di nuovo
- Dopo sette tentativi il gioco finisce, rivelando il numero segreto
Il punto 6 è quello che ti farà riflettere: ora il tuo ciclo può terminare per due motivi diversi — un'ipotesi giusta, oppure i tentativi che finiscono. Come organizzi le due uscite è la vera domanda di questo esercizio. E quando funziona, rileggi ancora una volta il tuo codice e chiediti: c'è uno stato in cui questo ciclo potrebbe arrivare e girare per sempre?
In questa missione c’è di più
Quello che hai letto sopra è la missione completa: non è stato tagliato nulla. Pro aggiunge:
- Cosa succede davvero dietro le quinte: come Python lo esegue
- La soluzione completa dell’esercizio, svolta passo per passo
- Esercizi extra più difficili
- La domanda da colloquio su questo argomento, con una risposta modello
Passo 6 di 6
Sfida — il quiz del capitolo
Dieci domande dalla più facile alla più difficile. Le ultime sono difficili di proposito.
Accedi per fare il quiz