In Python esistono due tipi di cicli (anche detti loop):
- il ciclo
for
- il ciclo
while
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
for
in
:
- dopo i due punti è presente un blocco di codice indentato (che può anche essere formato da più righe);
- il ciclo
for
n
- in questo esempio la variabile
n
1
2
3
4
5
- una volta che il blocco di codice è stato eseguito per tutti i valori, il ciclo
for
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
while
len(seq) > 3
:
- dopo i due punti è presente un blocco di codice indentato (che può anche essere formato da più righe);
- il ciclo
while
- in questo caso rimuove e stampa gli elementi di
seq
seq
- una volta che la sequenza è rimasta con solo 3 elementi, la condizione
len(seq) > 3
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
continue
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
if
for
for-else
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