Iteracja to ogólny termin określania każdego elementu czegoś, jeden po drugim. Za każdym razem, gdy używasz pętli, jawnej lub niejawnej, aby przejść przez grupę elementów, to znaczy iterację.
W Pythonie iterowalność i iterator mają określone znaczenie.
Iterowalny jest obiektem, który ma __iter__
sposobu, który zwraca się iteracyjnej , albo który definiuje __getitem__
sposób, że może przyjmować indeksy kolejnych zaczynając od zera (i podnosi IndexError
przy indeksy nie obowiązuje). I tak iterowalny to obiekt, z którego można uzyskać iterator .
Iteracyjnej Przedmiotem z next
(Python 2) lub __next__
(3 Python) sposobu.
Za każdym razem, gdy używasz for
pętli lub map
zrozumienia listy itp. W Pythonie, next
metoda jest wywoływana automatycznie, aby pobrać każdy element z iteratora , przechodząc przez to proces iteracji .
Dobrym miejscem do rozpoczęcia nauki byłaby sekcja iteratorów samouczka i sekcja typów iteratorów na stronie typów standardowych . Po zrozumieniu podstaw wypróbuj sekcję iteratorów w HOWTO Programowanie funkcjonalne .
collections.abc.AsyncIterator
testy__aiter__
i__anext__
metody. To jest nowy dodatek w wersji 3.6.__len__
być koniecznie związany z iteracją? W jaki sposób znajomość długości czegoś pomogłaby Ci w iteracji?__getitem__
.{'a': 'hi', 'b': 'bye'}
ma on długość 2, ale nie może być indeksowany przez 0, 1 lub 2.__iter__
metodę. Myślę, że jlh odnosi się do obiektów, które są iterowalne, ponieważ definiują: „__getitem__
metodę, która może pobierać indeksy sekwencyjne, zaczynając od zera”.Oto wyjaśnienie, którego używam do nauczania klas Python:
ITERABLE to:
for x in iterable: ...
lubiter()
, zwróci ITERATOR:iter(obj)
lub__iter__
który zwraca świeży ITERATOR, lub może mieć__getitem__
metodę odpowiednią do wyszukiwania indeksowanego.ITERATOR to obiekt:
__next__
sposobie tym:StopIteration
__iter__
metodę, która zwracaself
).Uwagi:
__next__
Sposób Pythonie 3 jest opisananext
w Pythonie 2 inext()
wywołuje tę metodę na obiekcie do niej przekazanym.Na przykład:
źródło
for
pętli, a pierwszy pocisk dotyczy „zapętlenia”. Czy możesz to rozwiązać?iter()
”, „jak” wszystko, co można przekazaćiter()
”Powyższe odpowiedzi są świetne, ale jak większość tego, co widziałem, nie podkreślaj wystarczająco rozróżnienia dla ludzi takich jak ja.
Ponadto ludzie mają skłonność do „zbyt Pythonic”, umieszczając definicje takie jak „X to obiekt, który ma
__foo__()
metodę” wcześniej. Takie definicje są poprawne - opierają się na filozofii pisania kaczego, ale skupienie się na metodach zwykle występuje pomiędzy próbą zrozumienia pojęcia w jego prostocie.Więc dodaję swoją wersję.
W języku naturalnym
W Pythonie
iterowalny to obiekt, który jest, cóż, iterowalny, co po prostu oznacza, że można go użyć w iteracji, np. z
for
pętlą. W jaki sposób? Za pomocą iteratora . Wyjaśnię poniżej.... podczas gdy iterator jest obiektem, który definiuje sposób wykonywania iteracji - w szczególności jaki jest następny element. Dlatego musi mieć
next()
metodę.Iteratory również są iterowalne, z tą różnicą, że ich
__iter__()
metoda zwraca ten sam obiekt (self
), niezależnie od tego, czy jego elementy zostały wykorzystane przez poprzednie wywołania donext()
.Co myśli interpreter Pythona, gdy widzi
for x in obj:
oświadczenie?Ponieważ Panowi
obj
udało się w tym teście (mając pewną metodę zwracającą prawidłowy iterator), nagradzamy go przymiotnikiem: możesz teraz nazwać go „iterowalnym Panemobj
”.Jednak w prostych przypadkach zwykle nie korzysta się z iteratora i iteracji oddzielnie. Definiujesz więc tylko jeden obiekt, który jest także własnym iteratorem. (Python tak naprawdę nie przejmuje się tym, że
_i
przekazany przez niegoobj
nie był aż tak błyszczący, aleobj
sam w sobie).Oto dlaczego w większości przykładów, które widziałem (i co ciągle mnie myliło), możesz zobaczyć:
zamiast
Są jednak przypadki, w których możesz oddzielić iterator od iterowalnego, na przykład gdy chcesz mieć jeden wiersz elementów, ale więcej „kursorów”. Na przykład, jeśli chcesz pracować z elementami „bieżącymi” i „nadchodzącymi”, możesz mieć osobne iteratory dla obu. Lub wiele wątków wyciąganych z ogromnej listy: każdy może mieć swój iterator do przechodzenia między wszystkimi elementami. Zobacz odpowiedzi @ Raymond i @ glglgl powyżej.
Wyobraź sobie, co możesz zrobić:
Uwagi:
Powtórzę jeszcze raz: iterator nie jest powtarzalny . Iteratora nie można używać jako „źródła” w
for
pętli. Tafor
pętla przede wszystkim potrzebuje__iter__()
(która zwraca cośnext()
).Oczywiście
for
nie jest to jedyna pętla iteracyjna, więc powyższe dotyczy również niektórych innych konstrukcji (while
...).Iterator
next()
może rzucić StopIteration, aby zatrzymać iterację. Nie musi jednak iterować wiecznie lub używać innych środków.W powyższym „procesie myślowym”
_i
tak naprawdę nie istnieje. Wymyśliłem to imię.W Pythonie 3.x wprowadzono niewielką zmianę:
next()
należy wywołać metodę (nie wbudowaną)__next__()
. Tak, tak powinno być przez cały czas.Możesz również pomyśleć o tym w ten sposób: iterowalny ma dane, iterator pobiera następny element
Uwaga: Nie jestem programistą żadnego interpretera języka Python, więc tak naprawdę nie wiem, co interpreter „myśli”. Rozważania powyżej są jedynie demonstracją tego, jak rozumiem ten temat na podstawie innych wyjaśnień, eksperymentów i rzeczywistych doświadczeń początkującego Pythona.
źródło
for
pętla potrzebuje iteratora („Spójrz, pętla for. Wygląda jak zadanie dla iteratora ... Chodźmy.”). Ale potem w notatkach na końcu mówisz, że „Iteratora nie można używać jako źródła wfor
pętli” ...?pass
kod dla tychnext
definicji? Zakładam, że masz na myśli, że ktoś musi wdrożyć sposób na zdobycie następnego, ponieważ następny musi coś zwrócić.pass
jest .)pass
, myślę, że jest tam z powodów składniowych. Właśnie natknąłem się na odpowiedzi na obiekt elipsy, które są dość interesujące: możesz użyć,...
aby wskazać blok „todo later”.NotImplemented
jest również dostępny.for
pętli. Rozumiem sens twojej odpowiedzi i podoba mi się inaczej, ale myślę, że skorzystałoby na tym.Iterowalny to obiekt posiadający
__iter__()
metodę. Może być wielokrotnie powtarzany, na przykładlist()
s ituple()
s.Iterator to obiekt, który iteruje. Jest zwracany przez
__iter__()
metodę, zwraca się własną__iter__()
metodą i manext()
metodę (__next__()
w 3.x).Iteracja to proces nazywany tym
next()
resp.__next__()
dopóki się nie podniesieStopIteration
.Przykład:
źródło
Iterable
.Iterator
zawsze jestIterable
i jest własneIterator
, dwa wezwaniaiter()
niekoniecznie dają dwa niezależneIterator
s.Oto mój ściągawka:
Quiz: Czy widzisz, jak ...
__iter__()
metoda obiektu kontenera może być zaimplementowana jako generator?__next__
metodę niekoniecznie jest iteratorem?Odpowiedzi:
__iter__
metodę. Posiadanie__iter__
wystarczy, aby być iterowalnym. Dlatego każdy iterator jest iterowalny.Po
__iter__
wywołaniu powinien zwrócić iterator (return <iterator>
na powyższym schemacie). Wywołanie generatora zwraca iterator generatora, który jest rodzajem iteratora.Oto przykład:
źródło
__iter__
metodę. Czy możesz opracować drugi i trzeci punkt, edytując tę odpowiedź__iter__()
zwraca iterator. Generator jest iteratorem, więc można go w tym celu wykorzystać. do 3 .: Mogę tylko zgadywać tutaj, ale myślę, że jeśli__iter__()
brakuje lub nie wracaself
, to nie jest iterator, ponieważ iterator__iter__()
musi wrócićself
.Nie wiem, czy to komukolwiek pomaga, ale zawsze lubię wizualizować koncepcje w mojej głowie, aby je lepiej zrozumieć. Ponieważ mam małego syna, wizualizuję koncepcję iteracji / iteratora z cegieł i białego papieru.
Załóżmy, że jesteśmy w ciemnym pokoju, a na podłodze mamy cegły dla mojego syna. Cegły różnej wielkości, koloru nie mają teraz znaczenia. Załóżmy, że mamy 5 takich cegieł. Te 5 klocków można opisać jako przedmiot - powiedzmy zestaw klocków . Za pomocą tego zestawu klocków możemy zrobić wiele rzeczy - możemy wziąć jedną, a następnie drugą, a następnie trzecią, możemy zmienić miejsce cegieł, umieścić pierwszą cegłę nad drugą. Dzięki nim możemy robić wiele różnych rzeczy. Dlatego ten zestaw klocków jest powtarzalnym przedmiotem lub sekwencją, ponieważ możemy przejść przez każdą cegłę i coś z tym zrobić. Możemy to zrobić tylko jak mój synek - możemy grać jedną cegłą na raz . Więc znów wyobrażam sobie, że jestem tym zestawem klockówiterowalne .
Pamiętajcie, że jesteśmy w ciemnym pokoju. Lub prawie ciemno. Chodzi o to, że nie widzimy wyraźnie tych cegieł, jaki mają kolor, jaki kształt itp. Więc nawet jeśli chcemy coś z nimi zrobić - inaczej przez nie iterować - tak naprawdę nie wiemy co i jak, ponieważ to jest zbyt ciemno.
To, co możemy zrobić, jest blisko pierwszej cegły - jako element zestawu cegieł - możemy położyć kawałek białego papieru fluorescencyjnego, abyśmy mogli zobaczyć, gdzie jest pierwszy element z cegły. I za każdym razem, gdy wyjmujemy klocek z zestawu, zamieniamy biały kawałek papieru na następny klocek, aby móc to zobaczyć w ciemnym pokoju. Ta biała kartka papieru to nic innego jak iterator . To także przedmiot . Ale przedmiot z czym możemy pracować i bawić się elementami naszego iterowalnego obiektu - zestaw klocków.
To, nawiasem mówiąc, wyjaśnia mój wczesny błąd, kiedy próbowałem następujących w IDLE i otrzymałem błąd TypeError:
Lista X tutaj była naszym zestawem klocków, ale NIE była to biała kartka papieru. Najpierw musiałem znaleźć iterator:
Nie wiem, czy to pomaga, ale pomogło mi. Byłbym wdzięczny, gdyby ktoś mógł potwierdzić / poprawić wizualizację koncepcji. Pomoże mi to dowiedzieć się więcej.
źródło
Iterowalny : - coś, co jest iterowalne, jest iterowalne; takie jak sekwencje, takie jak listy, ciągi znaków itp. Ma także
__getitem__
metodę lub__iter__
metodę. Teraz, jeśli użyjemyiter()
funkcji na tym obiekcie, otrzymamy iterator.Iterator : - Kiedy otrzymamy obiekt iteratora z
iter()
funkcji; wywołujemy__next__()
metodę (w python3) lub po prostunext()
(w python2), aby uzyskać elementy jeden po drugim. Ta klasa lub instancja tej klasy nazywana jest iteratorem.Z dokumentów: -
Zastosowanie iteratorów przenika i ujednolica Pythona. Za kulisami instrukcja for wywołuje
iter()
obiekt kontenera. Funkcja zwraca obiekt iteratora, który definiuje metodę,__next__()
która uzyskuje dostęp do elementów w kontenerze pojedynczo. Gdy nie ma już więcej elementów,__next__()
generuje wyjątek StopIteration, który informuje pętlę for o zakończeniu. Możesz wywołać__next__()
metodę za pomocąnext()
wbudowanej funkcji; ten przykład pokazuje, jak to wszystko działa:Ex z klasy: -
źródło
Nie sądzę, że można to zrobić znacznie prościej niż w dokumentacji , ale spróbuję:
Możesz myśleć, że Iterator to pseudo-metoda pomocnicza (lub pseudo-atrybut), która daje (lub przechowuje) następny (lub pierwszy) element w iterowalnym . (W praktyce jest to tylko obiekt definiujący metodę
next()
)Iterację najlepiej tłumaczy definicja słowa Merriam-Webster :
źródło
więc,
iterable
to obiekt, który można zapętlić . np. lista, ciąg, krotka itp.użycie
iter
funkcji na naszymiterable
obiekcie zwróci obiekt iteratora.teraz ten obiekt iteratora ma metodę o nazwie
__next__
(w Pythonie 3 lub tylkonext
w Pythonie 2), za pomocą której można uzyskać dostęp do każdego elementu iterowalnego.więc WYDAJNOŚĆ POWYŻSZEGO KODU BĘDZIE:
1
2)
źródło
Luciano Ramalho, płynny Python.
źródło
Przed przystąpieniem do iteracji i iteratora głównym czynnikiem decydującym o iteracji i iteratorze jest sekwencja
Sekwencja: Sekwencja to zbiór danych
Iterable: Iterable to obiekt typu sekwencji obsługujący
__iter__
metodę.Metoda Iter: Metoda Iter przyjmuje sekwencję jako dane wejściowe i tworzy obiekt zwany iteratorem
Iterator: Iterator to obiekt, który wywołuje następną metodę i przechodzi przez sekwencję. Po wywołaniu następnej metody zwraca obiekt, który aktualnie przemierzał.
przykład:
x jest sekwencją, która składa się z gromadzenia danych
Po wywołaniu
iter(x)
zwraca iterator tylko wtedy, gdy obiekt x ma metodę iterującą, w przeciwnym razie zgłaszany jest wyjątek. Jeśli zwraca iterator, to y jest przypisywane w następujący sposób:Ponieważ y jest iteratorem, dlatego obsługuje on
next()
metodęPo wywołaniu metody następnej kolejno zwraca poszczególne elementy listy.
Po zwróceniu ostatniego elementu sekwencji, jeśli ponownie wywołamy następną metodę, zgłosi błąd StopIteration
przykład:
źródło
W Pythonie wszystko jest przedmiotem. Kiedy mówi się, że obiekt jest iterowalny, oznacza to, że możesz przechodzić przez (tj. Iterować) obiekt jako kolekcję.
Na przykład tablice są iterowalne. Możesz przejść przez nie za pomocą pętli for i przejść od indeksu 0 do indeksu n, gdzie n jest długością obiektu tablicy minus 1.
Słowniki (pary klucz / wartość, zwane także tablicami asocjacyjnymi) również są iterowalne. Możesz przejść przez ich klucze.
Oczywiście obiektów, które nie są kolekcjami, nie można powtarzać. Na przykład obiekt bool ma tylko jedną wartość, True lub False. Nie jest iterowalny (nie miałoby sensu, aby był to obiekt iterowalny).
Czytaj więcej. http://www.lepus.org.uk/ref/companion/Iterator.xml
źródło
iter()
standardowych typów kolekcji są iterowalne, ale same w sobie nie są kolekcjami.