08. Il Ciclo for e la funzione range
In questa lezione parleremo del secondo loop (o ciclo) di Python, il ciclo for, e introdurremo una nuova funzione molto importante, la funzione range.
Il Ciclo for in Python
Il for loop viene utilizzato in maniera simile al while loop di cui abbiamo parlato nella lezione precedente: essendo entrambi cicli, permettono di ripetere l'esecuzione di una determinata porzione di codice più volte. Tuttavia, le differenze nei meccanismi di funzionamento ne rendono preferibile uno rispetto all'altro a seconda del contesto in cui ci si trova.
A livello logico, la differenza col ciclo while è che invece di eseguire il blocco di codice interessato finché la condizione di controllo resta True, il ciclo for esegue questa sezione di programma per un numero specifico di cicli.
Qui di seguito uno dei programmi che abbiamo scritto nella lezione precedente, che come ricorderete da in output i numeri da 0 a 10:
counter = 0
while counter <= 10:
print(counter)
counter += 1
Riassumendone brevemente il funzionamento, abbiamo una variabile contatore inizializzata a 0, e fintato che il valore associato alla variabile risulta minore o uguale a 10, viene ripetuto un ciclo di codice in cui viene mandato in output il suo contenuto, sommandoci poi 1 prima di ripetere il loop.
Ma cosa mi direste se vi dicessi che possiamo ottenere il medesimo risultato più velocemente utilizzando stavolta il ciclo for di Python?
Per più velocemente intendo che possiamo eliminare sia la variabile contatore che la riga di codice necessaria ad incrementarne il valore: questo perché come abbiamo detto, la particolarità del for loop è che viene eseguito un numero definito di volte!
for numero in range(11):
print(numero)
Eseguiamo nuovamente il codice:
# output:
0
1
2
3
4
5
6
7
8
9
10
Vi starete forse chiedendo: com'è possibile che quando usiamo il for con la variabile numero, essa può essere riconosciuta automaticamente se non è stata prima definita?
In Python, quando si usa un ciclo for, la variabile specificata viene inizializzata dal ciclo stesso. Ad ogni iterazione del ciclo, questa assume il valore relativo nell'iterabile.
In altre parole, non è necessario definire o inizializzare la variabile numero prima del ciclo for. Il ciclo for si occupa sia della creazione che dell'assegnazione del valore alla variabile ad ogni passo.
La funzione range in Python
Abbiamo ottenuto lo stesso risultato ottenuto col while loop, ma utilizzando stavolta solo 2 righe di codice invece di 4. Eppure sono certo che in molti tra voi si staranno chiedendo: cos'è quella funzione range() e come mai le ho passato 11 invece di 10? E soprattutto, come funziona esattamente il ciclo for?
La funzione range() ci permette di impostare un intervallo di esecuzione tanto ampio quanto il numero che le passiamo come parametro, senza però includere il numero passato in sé. Di default, la funzione range() di Python inizia a contare a partire da 0; per comodità potete pensare a questo intervallo come a una sorta di lista, in questo caso di 11 elementi, da 0 a 10 inclusi.
Come abbiamo detto, a differenza del ciclo while, il ciclo for esegue la sua porzione di codice un numero preimpostato di volte, giusto? L'intervallo di range() corrisponde al numero di iterazioni che verranno eseguite, ovvero al numero di volte che il for loop verrà processato.
Di seguito un diagramma di flusso per il ciclo for in cui viene illustrato il funzionamento del codice scritto in precedenza:
Una volta che si entra all'interno del loop, il codice indentato relativo viene eseguito in loop fino a che non si arriva alla fine dell'intervallo di range(), momento in cui il ciclo termina.
Nota: in questo esempio si è scelto di utilizzare n come nome della variabile invece di numero, ma il funzionamento resta lo stesso. Altri nome comuni in questi casi sono i (da index, o indice) e l'underscore _, usato spesso quando non si da molta importanza alla variabile in sé.
I parametri della funzione range: start, stop e step
Ora che abbiamo imparato come funziona un ciclo for e a cosa serve la funzione range() di Python, vediamo un po' come poter ottenere il massimo da questa, in quanto dovete sapere che possiamo passarle ben 3 parametri.
Questo ci permette di impostare oltre a un punto di inizio dell'intervallo anche un punto di fine personalizzato, e un passo di avanzamento.
Modifichiamo il for loop utilizzato prima: impostiamo un punto di inizio a 3, manteniamo il punto di fine come 11, e settiamo anche un passo di 2
for numero in range(3, 11, 2):
print(numero)
# output
3
5
7
9
La differenza più grande è che stavolta il passo dell'intervallo è 2, quindi si passa da 3 a 5, da 5 a 7 e da 7 a 9. Come al solito il numero finale dell'intervallo viene saltato.
Modifichiamo ora il nostro codice in modo da invertire l'ordine dei valori restituiti rispetto all'esempio precedente, in modo quindi da ottenere i numeri da 10 a 0. Come punto di inizio dell'intervallo impostiamo 10, come valore finale -1 (ricordando che l'ultimo valore non viene considerato!) e come passo di avanzamento -1:
for numero in range(10, -1, -1):
print(numero)
# output
10
9
8
7
6
5
4
3
2
1
0