0Pricing
Python Academy · Lezione

Il protocollo degli iteratori

Comprendere __iter__ e __next__

Il protocollo degli iteratori è una lezione Python Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Python Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Python Academy include 4 lezioni in totale.

Che cos'è l'iterazione?

Ogni volta che si scrive un ciclo for su una lista, una stringa o un dizionario, Python utilizza il protocollo degli iteratori in background.

Un oggetto su cui è possibile eseguire un ciclo è detto iterabile. L'oggetto che produce effettivamente i valori uno alla volta è detto iteratore.

for ch in 'abc':
    print(ch)

iter() e next()

Due funzioni integrate gestiscono l'iterazione:

  • iter(obj) chiede a un iterabile di restituire il proprio iteratore.
  • next(it) chiede all'iteratore il valore successivo.

Quando non ci sono più valori, next() genera StopIteration.

it = iter([10, 20, 30])
print(next(it))
print(next(it))
print(next(it))

StopIteration

Richiamare next() una volta di troppo genera StopIteration. Un ciclo for intercetta automaticamente questa eccezione e si arresta correttamente.

it = iter([1])
print(next(it))
try:
    next(it)
except StopIteration:
    print('No more items')

I due metodi dunder

Per creare un iteratore personalizzato è necessario implementare due metodi:

  • __iter__ restituisce l'oggetto iteratore stesso.
  • __next__ restituisce il valore successivo o genera StopIteration.
class Count:
    def __init__(self, n):
        self.i = 0
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        if self.i >= self.n:
            raise StopIteration
        self.i += 1
        return self.i

for x in Count(3):
    print(x)

Iterabile e iteratore a confronto

Un iterabile deve avere solo __iter__. Un iteratore deve avere sia __iter__ sia __next__.

Le liste sono iterabili, ma non iteratori: ogni chiamata a iter() restituisce un nuovo iteratore.

nums = [1, 2, 3]
print(iter(nums) is iter(nums))
it = iter(nums)
print(it is iter(it))

Gli iteratori si esauriscono una sola volta

Un iteratore può essere consumato solo una volta. Dopo aver raggiunto la fine, rimane vuoto. Per eseguire di nuovo il ciclo, è necessario creare un nuovo iteratore.

it = iter([1, 2])
print(list(it))
print(list(it))

Un iteratore simile a range

Creiamo un iteratore personalizzato che si comporta come un semplice contatore. Noti come lo stato risieda nell'istanza.

class EvenUpTo:
    def __init__(self, limit):
        self.cur = 0
        self.limit = limit
    def __iter__(self):
        return self
    def __next__(self):
        if self.cur > self.limit:
            raise StopIteration
        value = self.cur
        self.cur += 2
        return value

print(list(EvenUpTo(8)))

Separare iterabile e iteratore

Un design più ordinato mantiene separati il contenitore e l'iteratore, così è possibile eseguire il ciclo sul contenitore molte volte.

class Bag:
    def __init__(self, items):
        self.items = items
    def __iter__(self):
        return BagIterator(self.items)

class BagIterator:
    def __init__(self, items):
        self.items = items
        self.i = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.i >= len(self.items):
            raise StopIteration
        v = self.items[self.i]
        self.i += 1
        return v

b = Bag(['x', 'y'])
print(list(b))
print(list(b))

Usare next() con un valore predefinito

next(it, default) restituisce il valore predefinito invece di generare StopIteration quando l'iteratore è vuoto. È utile per esaminare il valore successivo in modo sicuro.

it = iter([42])
print(next(it, 'done'))
print(next(it, 'done'))

Gli iteratori ottimizzano l'uso della memoria

Gli iteratori restituiscono un elemento alla volta, quindi non devono conservare in memoria l'intera sequenza. Per questo possono gestire flussi enormi o persino infiniti.

class Naturals:
    def __init__(self):
        self.n = 0
    def __iter__(self):
        return self
    def __next__(self):
        self.n += 1
        return self.n

it = iter(Naturals())
print(next(it), next(it), next(it))

Built-in che consumano iteratori

Molti built-in accettano qualsiasi iteratore: sum, max, min, sorted, list, tuple. Prelevano valori fino a StopIteration.

class Count:
    def __init__(self, n):
        self.i = 0
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        if self.i >= self.n:
            raise StopIteration
        self.i += 1
        return self.i

print(sum(Count(5)))
print(max(Count(5)))

Verifica rapida

Verifichi la Sua comprensione del protocollo degli iteratori.

Riepilogo

Ha imparato il protocollo degli iteratori:

  • iter() ottiene un iteratore; next() preleva i valori.
  • StopIteration segnala la fine e for la gestisce.
  • Gli iteratori personalizzati implementano __iter__ e __next__.
  • Gli iteratori sono utilizzabili una sola volta e consumano poca memoria.

Ora lascerà che sia Python a scrivere gli iteratori per Lei con yield.

Domande Frequenti

La lezione «Il protocollo degli iteratori» è gratuita?

Sì — il testo completo di «Il protocollo degli iteratori» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Python Academy, passa a CoddyKit PRO. Il corso Python Academy include 4 lezioni in totale.

Cosa imparerò in «Il protocollo degli iteratori»?

Comprendere __iter__ e __next__ Eserciti Python Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Python Academy?

Non è richiesta alcuna esperienza precedente. Python Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Il protocollo degli iteratori»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Python Academy?

Sì. Ogni lezione Python Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Il protocollo degli iteratori
  2. Funzioni generatrici
  3. Espressioni generatrici
  4. yield from e delega
← Torna a Python Academy