Blog JSystems - z miłości do programowania

Iteratory



Iterator to obiekt pozwalający na sekwencyjny dostęp do kolejnych elementów. Aby stworzyć iterator musimy w klasie zaimplementować dwie funkcje - "__iter__()" i "__next__()". Funkcja "__iter__()" zwraca obiekt iteratora, a "__next__()" zwraca kolejne elementy. "__next__()" wywołuje też wyjątek "StopIteration" kiedy nie ma już więcej elementów do oddania. Przeanalizujmy poniższy przykład:


class IncrementIterator:

    def __init__(self, n):
        self.n = n
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.n == self.i:
            raise StopIteration
        self.i += 1
        return self.i

for e in IncrementIterator(10):
    print(e)


Przesłaniam metodę "__init__" w celu przekazania do obiektu maksymalnej wartości do której chcemy iterować. Metoda "__iter__" musi zwracać obiekt iterowalny, tak więc w tym przypadku zwracam "siebie" czyli obiekt w którym się znajduję. Metoda "__next__" powiększa o 1 i zwraca wewnątrzobiektową zmienną. Zwróć uwagę że w związku z taką konstrukcją obiekt "pamięta" jaką wartość oddał ostatnio. Przy każdym kolejnym wywołaniu "__next__" jest też sprawdzane czy nie dotarliśmy do maksimum do którego mieliśmy iterować, a jeśli tak to wywołujemy wyjątek "StopIteration". Pod deklaracją klasy iterujemy po naszym iteratorze. W wyniku działania dostajemy na konsoli kolejne liczby od 1 do 10. Jeśli raz przeiterujemy po naszym iteratorze, to nie ma możliwości jej "zresetowania". Aby zacząć liczyć od nowa, musimy stworzyć nowy obiekt.


Poprzedni przykład zakładał limit ilości zwracanych elementów. W Pythonie możemy tworzyć również nieskończone iteratory. Poniżej przykład:


class NieskonczonyIterator:
    x=0
    def __iter__(self):
        return self
    def __next__(self):
        self.x+=1
        return self.x

ni=NieskonczonyIterator()
for i in range(10):
    print(  next(ni)  )


Tym razem nie mamy metody "__init__" któraby ustawiała jakiś maksymalny próg zwracanych wartości. W metodzie "__next__" nie rzucam w związku z tym wyjątkiem "StopIteration". Mój iterator będzie więc podawał kolejne liczby bez ograniczeń. Pod przykładem iteratora prezentuję przykład pobierania wartości z takiego iteratora. Tym razem muszę posłużyć się funkcją "next" od obiektu iteratora by pobierać kolejne wartości.

Przyjdź do nas na szkolenie z języka Python! Mamy szereg szkoleń w ofercie, od podstawowych po aplikacje webowe z użyciem Django, analizę danych, tesowanie, machine learning i wiele innych.
Sprawdź dostępne szkolenia Python
Zapisz się do newslettera aby otrzymywać najnowsze świeżynki pojawiające się na blogu!