# Python/Iterazione

Python
Copertina Tutti i moduli · Sviluppo
* IntroduzionePython/Introduzione
* SintassiPython/Sintassi
* Tipi di DatiPython/Tipi di Dati
** NumeriPython/Numeri
** SequenzePython/Sequenze
** DizionariPython/Dizionari
** FilePython/File
* Strutture di controllo
** SelezionePython/Selezione
** IterazionePython/Iterazione
* LibreriePython/Librerie
* Strumenti utiliPython/Strumenti
* EsempiPython/Esempi
Modifica il sommario
Python ha solo l'istruzione while per implementare l'iterazione nel senso di altri linguaggi come il Pascal o il C:
Mentre l'istruzione for permette di iterare sugli elementi di una sequenza:
Entrambi i cicli ammettono due istruzioni:
* continue che permette di saltare le rimanenti istruzioni del ciclo passando all'iterazione successiva,
* break che termina il ciclo
* se è presente la clausola else, le sue istruzioni vengono eseguite se il ciclo termina normalmente, mentre non vengono eseguite se il ciclo termina a causa dell'istruzione break.

## while

L'istruzione while permette di ripetere un blocco di istruzioni fin quando si mantiene vera una certa condizione.
Ad esempio se vogliamo elencare i primi 10 numeri naturali:
Per elencare i primi 10 numeri pari:
Ma in generale while va usato quando non si conosce il numero di volte che il ciclo andrà ripetuto. Ad es. nella seguente successione l'uso di while è adeguato:
Una delle tante implementazioni del Crivello di Eratostene usa un paio di cicli while:

## for

L'istruzione for è molto diversa dall'omonima istruzione del Pascal o del C, non è un'istruzione di ciclo, ma è un iteratore su una sequenza.
Se a è array di stringhe, e voglio visualizzarle una sotto l'altra, in Pascal scriverò all'incirca:
In Python:
Durante l'esecuzione del ciclo for la variabile elemento viene collegata ad ognuno degli elementi della sequenza a: non servono indici, non serve sapere quanti sono gli elementi della sequenza, quando sono finiti termina il ciclo.
Ad esempio una funzione che sommi tutti gli elementi di una lista di numeri potrebbe essere:
Ora se volessi la media dei numeri contenuti in una lista, posso scrivere la funzione:
Peccato solo che che, per questioni di efficienza, Python abbia implementato tra le funzioni native la funzione add che produce lo stesso risultato della nostra funzione somma.
Se volessi implementare una ricerca sequenziale in una lista, potrei usare for nel seguente modo:
Se volessi avere non una funzione che mi dice semplicemente se l'elemento è contenuto in una lista ma qual è la sua posizione, potrei combinare l'iteratore for con la funzione enumerate che restituisce la coppia: posizione, elemento:
Anche qui peccato che Guido ci abbia preceduti e sempre per questioni di efficienza abbia implementato l'istruzioine in e il metodo index che fanno all'incirca quello che fanno le nostre funzioni contenuto e posizione.

## for: la trappola

L'iteratore for presenta un trabocchetto... Per capirlo, partiamo da un esempio. Abbiamo una lista che contiene vari numeri, vogliamo togliere tutti quelli pari:
Sembra funzionare perfettamente, ma non è così! Se tentiamo di togliere i numeri pari da quest'altra lista:
otteniamo un risultato sconcertante!
Cosa è successo, come mai a volte funziona e a volte no? Questi sono gli errori più insidiosi, appaiono solo a volte, e, tipicamente, quando fanno più danno.
Il fatto è che si deve assolutamente evitare di modificare la sequenza su cui l'iteratore for sta lavorando.
Nel primo caso (num=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) viene controllato il primo elemento di num, è pari e viene tolto. Ora il primo elemento è 1 e viene controllato il secondo, vale 2, è pari e viene tolto, ora il primo elemento è 1 e il secondo è 3, viene controllato il terzo che è pari e viene tolto...
Nel secondo caso (num1=[0, 1, 2, 4, 5, 6, 7, 8, 9]) viene controllato il primo elemento di num1, è pari e viene tolto. Ora il primo elemento è 1 e viene controllato il secondo, vale 2, è pari e viene tolto, ora il primo elemento è 1 e il secondo è 4, viene controllato il terzo che è 5, è dispari e viene lasciato, poi viene controllato il quarto elemento...
Regola fondamentale per non cadere nella trappola è: "mai modificare una lista mentre si sta iterando su di essa".
Allora, come si può realizzare l'operazione precedente? Basta iterare su una lista e modificarne un'altra, inizialmente identica. Ma come costruire una lista identica ad una già presente? Ci sono due costrutti Python che permettono di farlo:
Tenendo conto di questo si può riscrivere il comando precedente e provare che funziona: