Czym dokładnie jest iterator, iterowalność i iteracja?

442

Jaka jest najbardziej podstawowa definicja „iterowalnego”, „iteratora” i „iteracji” w Pythonie?

Przeczytałem wiele definicji, ale nie jestem w stanie zidentyfikować dokładnego znaczenia, ponieważ nadal nie chce się ono zatracić.

Czy ktoś może mi pomóc z 3 definicjami w kategoriach laika?

thechrishaddad
źródło

Odpowiedzi:

530

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 IndexErrorprzy 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 forpętli lub mapzrozumienia listy itp. W Pythonie, nextmetoda 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 .

agf
źródło
1
Zauważ, że collections.abc.AsyncIteratortesty __aiter__i __anext__metody. To jest nowy dodatek w wersji 3.6.
Janus Troelsen
1
@ jlh dlaczego miałby __len__być koniecznie związany z iteracją? W jaki sposób znajomość długości czegoś pomogłaby Ci w iteracji?
shadowtalker,
2
@shadowtalker pomogłoby wiedzieć, które indeksy są prawidłowe, więc wiesz, z którymi indeksami można korzystać __getitem__.
jlh
4
@ jlh brzmi to tak, jakbyś proponował bardzo uprzejme zachowanie dfeault. Weźmy pod uwagę, że {'a': 'hi', 'b': 'bye'}ma on długość 2, ale nie może być indeksowany przez 0, 1 lub 2.
shadowtalker
2
@shadowtalker. Ale dyktat ma __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”.
Bogaty
337

Oto wyjaśnienie, którego używam do nauczania klas Python:

ITERABLE to:

  • wszystko, co można zapętlić (tzn. można zapętlić ciąg lub plik) lub
  • wszystko, co może pojawić się po prawej stronie pętli for: for x in iterable: ...lub
  • wszystko, z czym możesz zadzwonić iter(), zwróci ITERATOR: iter(obj)lub
  • obiekt, który definiuje, __iter__który zwraca świeży ITERATOR, lub może mieć __getitem__metodę odpowiednią do wyszukiwania indeksowanego.

ITERATOR to obiekt:

  • ze stanem, który pamięta, gdzie jest podczas iteracji,
  • w __next__sposobie tym:
    • zwraca następną wartość z iteracji
    • aktualizuje stan, aby wskazywał następną wartość
    • sygnalizuje, kiedy odbywa się to przez podniesienie StopIteration
  • i to jest iterowalne (co oznacza, że ​​ma __iter__metodę, która zwraca self).

Uwagi:

  • __next__Sposób Pythonie 3 jest opisana nextw Pythonie 2 i
  • Wbudowana funkcja next()wywołuje tę metodę na obiekcie do niej przekazanym.

Na przykład:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable
Raymond Hettinger
źródło
co masz na myśli mówiąc o świeżym iteratorze?
lmiguelvargasf
13
@lmiguelvargasf „Świeży” jak w „nowy i nieużywany” w przeciwieństwie do „wyczerpany lub częściowo zużyty”. Chodzi o to, że nowy iterator zaczyna się na początku, podczas gdy częściowo używany iterator rozpoczyna pracę tam, gdzie go przerwał.
Raymond Hettinger
Twój drugi, trzeci i czwarty punkt wyraźnie wskazują, co masz na myśli, jeśli chodzi o konkretne konstrukcje python, wbudowane lub wywołania metod. Ale pierwszy pocisk („wszystko, co można zapętlić”) nie ma tej jasności. Ponadto pierwszy pocisk zdaje się pokrywać z drugim pociskiem, ponieważ drugi pocisk dotyczy forpętli, a pierwszy pocisk dotyczy „zapętlenia”. Czy możesz to rozwiązać?
Fountainhead
2
Pls rozważają ponowne sformułowanie „wszystko, co można nazwać iter()”, „jak” wszystko, co można przekazać iter()
Fountainhead
98

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

  • iteracja to proces pobierania jednego elementu na raz z rzędu elementów.

W Pythonie

  • iterowalny to obiekt, który jest, cóż, iterowalny, co po prostu oznacza, że ​​można go użyć w iteracji, np. z forpę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 do next().


Co myśli interpreter Pythona, gdy widzi for x in obj:oświadczenie?

Spójrz, forpętla. Wygląda na pracę dla iteratora ... Zdobądźmy ją. ... Jest ten objfacet, więc zapytajmy go.

„Panie obj, masz swój iterator?” (... wzywa iter(obj), który wzywa obj.__iter__(), który szczęśliwie rozdaje nowy błyszczący iterator _i).

OK, to było łatwe ... Zacznijmy od iteracji. ( x = _i.next()... x = _i.next()...)

Ponieważ Panowi objudało się w tym teście (mając pewną metodę zwracającą prawidłowy iterator), nagradzamy go przymiotnikiem: możesz teraz nazwać go „iterowalnym Panem obj”.

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 _iprzekazany przez niego objnie był aż tak błyszczący, ale objsam 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ć:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

zamiast

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

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ć:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Uwagi:

  • Powtórzę jeszcze raz: iterator nie jest powtarzalny . Iteratora nie można używać jako „źródła” w forpętli. Ta forpętla przede wszystkim potrzebuje __iter__() (która zwraca coś next()).

  • Oczywiście fornie 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” _itak 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.

Alois Mahdal
źródło
1
To świetnie - ale wciąż jestem trochę zdezorientowany. Myślałem, że twoje żółte pole mówi, że forpę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 w forpętli” ...?
Racing Tadpole
Dlaczego wstawiasz tylko passkod dla tych nextdefinicji? 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ć.
nealmcb
@nealmcb Tak, myślę, że o to mi chodziło. (W końcu po to passjest .)
Alois Mahdal
@AloisMahdal Ahh, nie widziałem tego zastosowania wcześniej. Kiedy widzę 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”. NotImplementedjest również dostępny.
nealmcb
Chociaż podoba mi się, że podkreślasz różnicę między iteratorem a iterowalnością, ta odpowiedź jest sprzeczna. Najpierw napisz: „Iteratory też są iterowalne” (co odpowiada temu, co napisano w dokumentacji Pythona ). Ale potem piszesz: „ iteratora nie da się powtórzyć . Iteratora nie można używać jako „źródła” w forpętli. Rozumiem sens twojej odpowiedzi i podoba mi się inaczej, ale myślę, że skorzystałoby na tym.
Bogaty
22

Iterowalny to obiekt posiadający __iter__()metodę. Może być wielokrotnie powtarzany, na przykład list()s i tuple()s.

Iterator to obiekt, który iteruje. Jest zwracany przez __iter__()metodę, zwraca się własną __iter__()metodą i ma next()metodę ( __next__()w 3.x).

Iteracja to proces nazywany tym next()resp. __next__()dopóki się nie podniesie StopIteration.

Przykład:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
glglgl
źródło
Czy to naprawdę obiekt przechodzący przez kontener? czy byłoby to przydatne?
thechrishaddad
Często, ale nie zawsze. Kursor generatora, pliku lub bazy danych można iterować tylko raz, a zatem są własnymi iteratorami.
glglgl
Chyba b2 nie musi być niezależne od b1? w tym szczególnym przypadku jest niezależny, na pewno mogę uczynić go niezależnym, ale także ważnym Iterable.
Bin
@ Bin Tak. Jak Iteratorzawsze jest Iterablei jest własne Iterator, dwa wezwania iter()niekoniecznie dają dwa niezależne Iterators.
glglgl,
13

Oto mój ściągawka:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Quiz: Czy widzisz, jak ...

  1. każdy iterator jest iterowalny?
  2. __iter__()metoda obiektu kontenera może być zaimplementowana jako generator?
  3. iterowalność, która ma __next__metodę niekoniecznie jest iteratorem?

Odpowiedzi:

  1. Każdy iterator musi mieć __iter__metodę. Posiadanie __iter__wystarczy, aby być iterowalnym. Dlatego każdy iterator jest iterowalny.
  2. 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.

    class Iterable1:
        def __iter__(self):
            # a method (which is a function defined inside a class body)
            # calling iter() converts iterable (tuple) to iterator
            return iter((1,2,3))
    
    class Iterable2:
        def __iter__(self):
            # a generator
            for i in (1, 2, 3):
                yield i
    
    class Iterable3:
        def __iter__(self):
            # with PEP 380 syntax
            yield from (1, 2, 3)
    
    # passes
    assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
  3. Oto przykład:

    class MyIterable:
    
        def __init__(self):
            self.n = 0
    
        def __getitem__(self, index: int):
            return (1, 2, 3)[index]
    
        def __next__(self):
            n = self.n = self.n + 1
            if n > 3:
                raise StopIteration
            return n
    
    # if you can iter it without raising a TypeError, then it's an iterable.
    iter(MyIterable())
    
    # but obviously `MyIterable()` is not an iterator since it does not have
    # an `__iter__` method.
    from collections.abc import Iterator
    assert isinstance(MyIterable(), Iterator)  # AssertionError
AXO
źródło
1
W quizie zrozumiałem tylko 1. punktor. tzn. iterator staje się iterowalny, ponieważ ma __iter__metodę. Czy możesz opracować drugi i trzeci punkt, edytując tę ​​odpowiedź
AnV
@AnV: O ile rozumiem: re 2 .: __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 wraca self, to nie jest iterator, ponieważ iterator __iter__()musi wrócić self.
glglgl
10

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:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

Lista X tutaj była naszym zestawem klocków, ale NIE była to biała kartka papieru. Najpierw musiałem znaleźć iterator:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

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.

Nikolay Dudaev
źródło
6

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żyjemy iter()funkcji na tym obiekcie, otrzymamy iterator.

Iterator : - Kiedy otrzymamy obiekt iteratora z iter()funkcji; wywołujemy __next__()metodę (w python3) lub po prostu next()(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:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Ex z klasy: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s
Vicrobot
źródło
4

Nie sądzę, że można to zrobić znacznie prościej niż w dokumentacji , ale spróbuję:

  • Iterowalność jest czymś, co można powtórzyć . W praktyce oznacza to zwykle sekwencję, np. Coś, co ma początek i koniec oraz jakiś sposób na przejrzenie wszystkich zawartych w nim elementów.
  • 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 :

b: powtórzenie sekwencji instrukcji komputerowych określoną liczbę razy lub do momentu spełnienia warunku - porównaj rekurencję

Kimvais
źródło
3
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

więc,

  1. iterableto obiekt, który można zapętlić . np. lista, ciąg, krotka itp.

  2. użycie iterfunkcji na naszym iterableobiekcie zwróci obiekt iteratora.

  3. teraz ten obiekt iteratora ma metodę o nazwie __next__(w Pythonie 3 lub tylko nextw 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)

Arpan Kumar
źródło
3

Iterables mają __iter__metodę, która za każdym razem tworzy instancję nowego iteratora.

Iteratory implementują __next__metodę zwracającą poszczególne elementy oraz __iter__metodę zwracającą self.

Dlatego iteratory również są iterowalne, ale iteratory nie są iteratorami.

Luciano Ramalho, płynny Python.

techkuz
źródło
2

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=[1,2,3,4]

x jest sekwencją, która składa się z gromadzenia danych

y=iter(x)

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:

y=[1,2,3,4]

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:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
Cień
źródło
Tylko obserwacja: y = iter (x) nie jest dokładnie y = [1,2,3,4], ponieważ y jest teraz obiektem iteratora. Być może powinieneś dodać komentarz, aby wyjaśnić, że nie jest to lista, ale obiekt iteratora lub zmienić reprezentację.
coelhudo
-6

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

użytkownik93097373
źródło
6
obiekty, które nie są kolekcjami, które nie są iterowalne, zasadniczo nie są prawdziwe. Aby podać tylko kilka przykładów, generatory są iterowalne, ale nie są kolekcjami, a obiekty iteratora utworzone przez wywołanie iter()standardowych typów kolekcji są iterowalne, ale same w sobie nie są kolekcjami.
Mark Amery