Blog JSystems - uwalniamy wiedzę!

Szukaj
Animacja iteratora - element po elemencie
Iterator oddaje kolejne elementy przez next(), aż zgłosi StopIteration

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.

Szkolenie Python od podstaw, przez analizę danych, do machine learning w JSystems

Ten kurs daje Ci solidne podstawy Pythona. Jeśli chcesz pójść dalej i pod okiem trenera dojść od pierwszej linijki kodu do własnego modelu uczenia maszynowego, sprawdź nasze pięciodniowe szkolenie Python od podstaw, przez analizę danych, do machine learning. Pierwsze trzy dni to Python w praktyce: typy i kolekcje, instrukcje warunkowe i pętle, funkcje, moduły i pakiety, pliki tekstowe, usługi sieciowe oraz praca z bazą PostgreSQL. Czwarty dzień to analiza danych w pandas (wczytywanie CSV, TSV i XLS, filtrowanie, agregacje, statystyki) i wizualizacja w Matplotlib, Seaborn oraz Plotly. Piąty dzień to uczenie maszynowe w scikit-learn: regresja liniowa i logistyczna, drzewa decyzyjne, las losowy, XGBoost, walidacja predykcji, dobór hiperparametrów i przeciwdziałanie przeuczeniu. Szkolenie ma terminy gwarantowane, czyli odbywa się niezależnie od wielkości grupy.

Szkolenie Python od podstaw, przez analizę danych, do machine learning

To szkolenie może być dofinansowane dla Ciebie z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Jakie metody trzeba zaimplementować, aby stworzyć iterator w Pythonie?
Klasa musi mieć dwie metody: __iter__, która zwraca obiekt iteratora, oraz __next__, która oddaje kolejne elementy. Metoda __next__ zgłasza wyjątek StopIteration, gdy nie ma już więcej elementów do zwrócenia.
Do czego służy wyjątek StopIteration?
StopIteration sygnalizuje, że iterator wyczerpał wszystkie elementy. Metoda __next__ rzuca ten wyjątek, gdy dojdzie do końca, a pętla for wychwytuje go i kończy iterację. Bez niego pętla nie wiedziałaby, kiedy przestać.
Czy iterator można zresetować i przejść po nim ponownie?
Nie da się go zresetować. Gdy raz przejdziesz po iteratorze do końca, aby zacząć od nowa musisz utworzyć nowy obiekt. Poprzedni obiekt pamięta swój stan i nie wróci do początku.
Jak działa nieskończony iterator?
Nieskończony iterator nie ma warunku zatrzymania, więc jego metoda __next__ nie zgłasza StopIteration i podaje kolejne wartości bez ograniczeń. Wartości pobierasz z niego funkcją next, kontrolując liczbę pobrań z zewnątrz, na przykład pętlą z range.
Dlaczego iterator pamięta, jaki element oddał ostatnio?
Iterator przechowuje swój stan w zmiennych obiektu, na przykład w polu licznika. Przy każdym wywołaniu __next__ ta zmienna jest zwiększana i zwracana, dzięki czemu obiekt wie, gdzie skończył i który element podać jako następny.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...