Corso Python / Cicli for con range, enumerate e zip

Il ciclo for elabora uno alla volta gli elementi di un oggetto iterabile. Leggi direttamente i valori quando bastano, usa enumerate() per aggiungere un contatore e zip() per attraversare insieme collezioni collegate.

Attraversare valori o intervalli numerici

Un iterabile è un oggetto da cui si possono ottenere elementi in successione, come una lista o una stringa. In Python non devi necessariamente aumentare a mano un indice: for name in names fornisce direttamente ogni nome. Il corpo del ciclo è rientrato dopo il due punti.

range(start, stop, step) rappresenta una progressione di interi. Il valore stop è escluso; con passo negativo la progressione scende. Il passo non può essere zero. Un range non contiene già una lista materializzata di tutti i suoi elementi: usa list() quando vuoi mostrarli come lista.

for value in range(1, 4):
    print(value)

Il risultato è 1, 2 e 3, ciascuno su una riga. Il limite 4 non viene incluso. Se inizio e fine non sono compatibili con il segno del passo, il range può essere vuoto e il corpo del ciclo non viene eseguito.

Abbinare nomi e importi con un numero di visualizzazione

Salva il programma completo in UTF-8 come for_loop.py in una cartella di esercitazione. Usa Python 3.10 o successivo, perché l’esempio richiede zip(..., strict=True). Esegui python for_loop.py con l’interprete del progetto; fuori dall’ambiente virtuale su macOS o Ubuntu usa python3 se è il comando dell’interprete scelto. Non servono librerie esterne.

names = ["coffee", "lunch", "bus"]
amounts = [3500, 8000, 2500]
for number, (name, amount) in enumerate(zip(names, amounts, strict=True), start=1):
    print(number, name, amount)
print(list(range(5, 0, -2)))

Il risultato atteso è:

1 coffee 3500
2 lunch 8000
3 bus 2500
[5, 3, 1]

zip() abbina coffee a 3500, lunch a 8000 e bus a 2500. enumerate() aggiunge un contatore che parte da 1; l’unpacking separa il numero e poi la coppia nome-importo. La guida alle tuple e all’unpacking spiega come riconoscere queste strutture annidate.

L’ultima riga mostra 5, 3 e 1: il passo è -2 e il limite escluso è 0. Per il risultato non basta guardare il segno del limite; segui la progressione e la regola di esclusione.

Controllare contatori e lunghezze degli input

enumerate(items, start=1) cambia il contatore fornito dal ciclo, non gli indici della lista. Il primo elemento della lista continua ad avere indice 0. Usa il valore già ottenuto nell’unpacking invece di indicizzare la lista con un numero pensato soltanto per la visualizzazione. La documentazione di enumerate descrive contatore e valore restituiti.

Di norma zip() si ferma quando termina l’input più corto e ignora gli elementi residui degli altri. Se le lunghezze devono coincidere, strict=True fa emergere la differenza con ValueError. L’opzione è disponibile da Python 3.10, come indicato nella documentazione ufficiale di zip.

Zip lavora quando viene consumato: con strict, l’errore può arrivare dopo che alcune coppie sono già state elaborate. Se togli l’ultimo importo dell’esempio, vengono stampate le prime due righe e poi compare l’errore; la stampa finale del range non viene raggiunta. Non interpretare strict come una verifica preventiva o come un annullamento delle operazioni già compiute.

Due liste parallele possono avere la stessa lunghezza e contenere comunque abbinamenti sbagliati. Quando i record diventano complessi, valuta una lista di dizionari o di record che tengano insieme nome e importo. La verifica della lunghezza non controlla il significato dei dati.

Provare limiti e sorgenti vuote senza modifiche inattese

  1. Togli 2500 da amounts lasciando strict: verifica le due righe stampate e il ValueError successivo.
  2. Togli anche strict=True: ora il programma termina normalmente dopo due coppie e stampa il range. Ripristina entrambe le liste e l’opzione.
  3. Cambia soltanto il limite del range finale da 0 a -1. Il risultato resta [5, 3, 1], perché -1 è escluso. Ripristina poi 0.
  4. Riesegui il file originale e confronta tutte le righe con il risultato atteso.

Una sorgente vuota fa eseguire zero iterazioni: qualsiasi totale o risultato da usare dopo il ciclo va inizializzato prima, se deve esistere anche senza elementi. Non presumere che la variabile del ciclo riceva sempre un valore.

Eliminare elementi dalla stessa lista che stai attraversando può farne saltare alcuni, perché cambiano le posizioni. La guida alle modifiche delle liste durante un ciclo mostra il problema. Se devi filtrare, raccogli un nuovo risultato oppure attraversa una copia, separando la lettura dalla modifica dei dati di origine.