
Differenza tra oggetto iteratore e iterabile
L'oggetto iteratore e l'oggetto iterabile non sono la stessa cosa, anche se sono strettamente correlati e spesso lavorano insieme.
- Iterabile
Un oggetto è iterabile se può essere iterato, ovvero se puoi attraversare i suoi elementi uno alla volta. Un oggetto è considerato iterabile se implementa il metodo speciale `__iter__()`, che restituisce un iteratore.Esempi comuni di oggetti iterabili sono le liste, le tuple, le stringhe, i dizionari e i set. Quando passi un iterabile a un ciclo `for`, Python chiama il metodo `__iter__()` dell'oggetto per ottenere un iteratore.
- Iteratore
Un iteratore è un oggetto che rappresenta uno stato di iterazione su una sequenza di elementi. Implementa i metodi speciali `__iter__()` e `__next__()`.- Il metodo `__iter__()` restituisce l'iteratore stesso in modo che possa essere utilizzato in un ciclo `for` o con `next()`
- Il metodo `__next__()` restituisce il prossimo elemento della sequenza. Quando non ci sono più elementi da restituire, solleva l'eccezione `StopIteration` per terminare l'iterazione.
Qual è la differenza?
Quando invochi `iter()` su un oggetto iterabile, Python chiama il metodo `__iter__()` di quell'oggetto, il quale restituisce un iteratore.
In altre parole, un oggetto iterabile fornisce un iteratore.
Ad esempio, una lista (`[1, 2, 3]`) è un oggetto iterabile. Quando chiami `iter()` sulla lista, ottieni un oggetto iteratore che ti permette di attraversare gli elementi della lista uno alla volta.
Viceversa, un iteratore è anche iterabile poiché un iteratore implementa `__iter__()` che restituisce se stesso.
In questo caso, però, puoi anche chiamare il metodo `__next__()` per leggere gli elementi.
Tuttavia, è importante notare che l'iterazione su un iteratore è distruttiva: una volta che un elemento è stato consumato dall'iteratore, non può essere iterato di nuovo, a meno che l'iteratore non venga ricreato.
Esempio
Immagina di avere una lista di numeri:
numbers = [1, 2, 3, 4, 5]
Questo è un oggetto iterabile
Quindi puoi usare un ciclo for per leggere tutti gli elementi uno dopo l'altro.
for item in numbers:
print(item)
1
2
3
4
5
Nota. Sugli oggetti iterabili non puoi usare la funzione next() perché il metodo '__next__()' non è implementato in questi oggetti.
Se chiami la funzione `iter()` sulla lista ottieni un oggetto iteratore:
iterator = iter(numbers)
Quest'ultimo è un oggetto iteratore
Questo significa che puoi usare anche la funzione `next()` sull'oggetto per ottenere gli elementi uno alla volta:
print(next(iterator))
1
Se continui a chiamare `next()` sull'iteratore, attraverserai tutti gli elementi della lista.
print(next(iterator))
2
Quando gli elementi sono finiti, verrà sollevata l'eccezione `StopIteration`.
Poiché un oggetto iteratore è anche iterabile, in alternativa puoi leggerlo tramite le iterazioni di un ciclo for.
for item in iterator:
print(item)
1
2
3
4
5
In sintesi, un iterabile è un oggetto da cui puoi ottenere un iteratore, mentre un iteratore è l'oggetto che ti permette di attraversare gli elementi di un iterabile.
Sebbene possano sembrare simili, servono a scopi leggermente diversi all'interno del flusso di iterazione in Python.