PYTHON: Iteratori Customizzati

Sono Iteratori creati ad-hoc dal programmatore, praticamente sono delle CLASSI che implementano almeno i due metodi __iter__() e __next__()

nel metodo __iter__() Avviene l’inizializzazione dell’iteratore e il suo return (di solito viene ritornato l’oggetto stesso)

nel metodo __next__() ritorna il prossimo elemento nella sequenza e solleva l’eccezione StopIteration alla fine degli elementi

Facciamo un esempio di un iteratore che ad ogni chiamata restituise il valore precedente aumentato di 1.44 partendo da 0

class numeri:
    #inizializzo l'iteratore partendo da 0
    def __iter__(self):
        self.x = 0
        return self

    #calcolo valore successivo restituito ad ogni chimata next(<oggetto>)
    def __next__(self):
        a = self.x
        self.x += 1.44
        return round(a,2)

oggetto = numeri()

#converto in iteratore
test = iter(oggetto)
#scorro iteratore
for i in range(0,100):
    print(next(test))

I commenti al codice dicono tutto, l’unica cosa e’ che questo iteratore non finira’ mai di generare in quanto nella dichiarazione del metodo __next__() non c’e’ limite, pertanto lanciando un for i in range(oggetto) il ciclo durerebbe all’infinito. Se ad esempio volessimo fermare la generazione al numero superiore a 144.00 dovremmo modificare il codice nel modo seguente:

class numeri:
    def __iter__(self):
        self.x=0
        return self
    def __next__(self):
        a = self.x
        self.x +=1.44
        if(a <= 144):
            return round(a,2)
        else:
            StopIteration
    
oggetto = numeri()

test = iter(oggetto)

for i in range (0,120):
    print(next(test))

In fine vediamo un esempio di iteratore customizzato con la possibilita’ di passergli dei parametri (esempio range(0,100):

class numeriDispari(object):
    def __init__(self, max):
        self.max = max #imposto il valore massimo
        self.n = -1 #imposto la partenza che sara sempre 1 
    
    def __next__(self):
        self.n += 2 #incremeto di 2 il valore precedente 
                    ( all inizio self.n = -1, quindi self.n + 2 = 1)
        if self.n > self.max:
            raise StopIteration #se supero il valore max fermo l'iterazione
        else:
            return self.n #altrimenti rimando il valore calcolato
    def __iter__(self):
        return self
    
#stampo i primi 10 numeri dipsari
numeri = numeriDispari(10)
for n in numeri:
    print(n)
#creo una lista dei primi 80 numeri dipari
numeri_d = [ x for x in numeriDispari(100) if x < 80]
print(numeri_d)

I commentio nel codice spiegano il funzionamento

Lascia un commento

Il tuo indirizzo email non sarĂ  pubblicato. I campi obbligatori sono contrassegnati *