In Python esistono due tipi di cicli (anche detti loop):
- il ciclo
for
: esegue un'iterazione per ogni elemento di un iterabile; - il ciclo
while
: itera fintanto che una condizione è vera.
Ciclo for
Il ciclo for
ci permette di iterare su tutti gli elementi di un iterabile ed eseguire un determinato blocco di codice. Un iterabile è un qualsiasi oggetto in grado di restituire tutti gli elementi uno dopo l'altro, come ad esempio liste, tuple, set, dizionari (restituiscono le chiavi), ecc.
Vediamo un semplice esempio di ciclo for
:
>>> # stampa il quadrato di ogni numero di seq
>>> seq = [1, 2, 3, 4, 5]
>>> for n in seq:
... print('Il quadrato di', n, 'è', n**2)
...
Il quadrato di 1 è 1
Il quadrato di 2 è 4
Il quadrato di 3 è 9
Il quadrato di 4 è 16
Il quadrato di 5 è 25
Possiamo notare che:
- il ciclo
for
è introdotto dalla keywordfor
, seguita da una variabile, dalla keywordin
, da un iterabile, e infine dai due punti (:
); - dopo i due punti è presente un blocco di codice indentato (che può anche essere formato da più righe);
- il ciclo
for
itera su tutti gli elementi della sequenza, li assegna alla variabilen
, ed esegue il blocco di codice; - in questo esempio la variabile
n
assumerà i valori di1
,2
,3
,4
, e5
e per ogni valore stamperà il quadrato; - una volta che il blocco di codice è stato eseguito per tutti i valori, il ciclo
for
termina.
Il seguente esempio mostra come sia possibile usare un if
all'interno di un ciclo for
:
>>> # determina se i numeri di seq sono pari o dispari
>>> seq = [1, 2, 3, 4, 5]
>>> for n in seq:
... print('Il numero', n, 'è', end=' ')
... if n%2 == 0:
... print('pari')
... else:
... print('dispari')
...
Il numero 1 è dispari
Il numero 2 è pari
Il numero 3 è dispari
Il numero 4 è pari
Il numero 5 è dispari
Anche in questo caso il blocco di codice viene eseguito 5 volte, una per ogni valore della sequenza.
Chi ha familiarità con altri linguaggi avrà notato che in Python il ciclo for
non usa indici che vengono incrementati manualmente (come ad esempio avviene in C), ma è invece più simile a costrutti quali il foreach
.
range
Dato che spesso accade di voler lavorare su sequenze di numeri, Python fornisce una funzione built-in chiamata range
che permette di specificare uno valore iniziale o start (incluso), un valore finale o stop (escluso), e uno step, e che ritorna una sequenza di numeri interi:
>>> range(5) # ritorna un oggetto range con start uguale a 0 e stop uguale a 5
range(0, 5)
>>> list(range(5)) # convertendolo in lista possiamo vedere i valori
[0, 1, 2, 3, 4]
>>> list(range(5, 10)) # con 2 argomenti si può specificare lo start e lo stop
[5, 6, 7, 8, 9]
>>> list(range(0, 10, 2)) # con 3 argomenti si può specificare anche lo step
[0, 2, 4, 6, 8]
Questa funzione è particolarmente utile se combinata con il ciclo for
:
>>> for n in range(1, 6):
... print('Il quadrato di', n, 'è', n**2)
...
Il quadrato di 1 è 1
Il quadrato di 2 è 4
Il quadrato di 3 è 9
Il quadrato di 4 è 16
Il quadrato di 5 è 25
range
può anche essere usato in combinazione con il ciclo for
se vogliamo ripetere un blocco di codice un numero fisso di volte:
>>> # stampa 'Python' 3 volte
>>> for x in range(3):
... print('Python')
...
Python
Python
Python
In questo caso si ottiene un comportamento più simile al for
"tradizionale" (come quello di C) e la variabile x
non è utilizzata.
Ciclo while
Il ciclo while
itera fintanto che una condizione è vera:
>>> # rimuovi e printa numeri da seq finchè ne rimangono solo 3
>>> seq = [10, 20, 30, 40, 50, 60]
>>> while len(seq) > 3:
... print(seq.pop())
...
60
50
40
>>> seq
[10, 20, 30]
Possiamo notare che:
- il ciclo
while
è introdotto dalla keywordwhile
, seguita da una condizione (len(seq) > 3
) e dai due punti (:
); - dopo i due punti è presente un blocco di codice indentato (che può anche essere formato da più righe);
- il ciclo
while
esegue il blocco di codice fintanto che la condizione è vera; - in questo caso rimuove e stampa gli elementi di
seq
fintanto che inseq
ci sono più di 3 elementi; - una volta che la sequenza è rimasta con solo 3 elementi, la condizione
len(seq) > 3
diventa falsa e il ciclo termina.
Alcuni altri linguaggi prevedono anche un costrutto chiamato do-while
, che esegue almeno un'iterazione prima di verificare la condizione. In Python questo costrutto non esiste, ma ottenere un risultato equivalente è molto semplice:
>>> # chiedi all'utente di inserire numeri finchè indovina
>>> n = 8
>>> while True:
... guess = int(input('Inserisci un numero da 1 a 10: '))
... if guess == n:
... print('Hai indovinato!')
... break # numero indovinato, interrompi il ciclo
... else:
... print('Ritenta sarai più fortunato')
...
Inserisci un numero da 1 a 10: 3
Ritenta sarai più fortunato
Inserisci un numero da 1 a 10: 5
Ritenta sarai più fortunato
Inserisci un numero da 1 a 10: 8
Hai indovinato!
In questo esempio, il ciclo while
viene usato per chiedere di inserire numeri finchè l'utente indovina il numero giusto (8
). La condizione usata è semplicemente True
, e siccome non può mai diventare falsa, si crea un ciclo infinito (endless loop). Il ciclo viene in realtà interrotto quando l'utente indovina il numero, usando un if
e la keyword break
.
break e continue
Python prevede 2 costrutti che possono essere usati nei cicli for
e while
:
break
: interrompe il ciclo;continue
: interrompe l'iterazione corrente e procede alla successiva.
Ad esempio, possiamo usare un ciclo for
per cercare un elemento in una lista e interrompere la ricerca appena l'elemento viene trovato:
>>> seq = ['alpha', 'beta', 'gamma', 'delta']
>>> for elem in seq:
... print('Sto controllando', elem)
... if elem == 'gamma':
... print('Elemento trovato!')
... break # elemento trovato, interrompi il ciclo
...
Sto controllando alpha
Sto controllando beta
Sto controllando gamma
Elemento trovato!
Non appena il ciclo raggiunge l'elemento 'gamma'
, la condizione dell'if
diventa vera e il break
interrompe il ciclo for
. Dall'output si può vedere che 'delta'
non viene controllato.
>>> seq = ['alpha', 'beta', 'gamma', 'delta']
>>> for elem in seq:
... if len(elem) == 5:
... continue # procedi all'elemento successivo
... print(elem)
...
beta
In questo esempio, invece, usiamo continue
per "saltare" le parole che hanno 5 lettere. Dall'output si può vedere che la condizione dell'if
è vera per 'alpha'
, 'gamma'
, e 'delta'
, e in questi casi l'iterazione procede immediatamente con l'elemento successivo senza eseguire il print
. Solo nel caso di 'beta'
(che ha 4 lettere), il continue
non viene eseguito e l'elemento viene stampato.
for-else e while-else
Una peculiarità di Python è la possibilità di aggiungere un else
al for
e al while
. Il blocco di codice nell'else
viene eseguito se il ciclo termina tutte le iterazioni. Se invece il ciclo è interrotto da un break
, l'else
non viene eseguito. La sintassi è simile a quella che abbiamo già visto con l'if
: l'else
deve essere indentato allo stesso livello del for
/while
, deve essere seguito dai due punti (:
) e da un blocco indentato.
Vediamo un esempio dove diamo all'utente 3 tentativi per indovinare un numero:
>>> n = 8
>>> for x in range(3):
... guess = int(input('Inserisci un numero da 1 a 10: '))
... if guess == n:
... print('Hai indovinato!')
... break # numero indovinato, interrompi il ciclo
... else:
... print('Tentativi finiti. Non hai indovinato')
...
Da notare che anche se l'else
segue l'if
, l'indentazione corrisponde a quella del for
: si tratta quindi di un for-else
, non di un if-else
.
Se l'utente riesce a indovinare il numero, la condizione dell'if
si avvera e il break
viene eseguito. In questo caso l'else
del for
non viene eseguito perché il ciclo for
è stato interrotto:
Inserisci un numero da 1 a 10: 3
Inserisci un numero da 1 a 10: 8
Hai indovinato!
Se invece l'utente non riesce ad indovinare il numero in 3 tentativi, il ciclo for
termina tutte le iterazioni e l'else
del for
viene eseguito.
Inserisci un numero da 1 a 10: 3
Inserisci un numero da 1 a 10: 5
Inserisci un numero da 1 a 10: 7
Tentativi finiti. Non hai indovinato