Czym dokładnie są iterator, iterable i iteracja?

Jakie są najbardziej podstawowe definicje "iterable", "iterator" i " iteracja w Pythonie?

Czytałem wiele definicji, ale ich dokładne znaczenie nadal nie zagości.

Czy ktoś może mi pomóc z podstawowym pomysłem?

Author: abccd, 2012-03-27

12 answers

Iteracja jest ogólnym terminem na przyjmowanie 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, czyli iterację.

W Pythonie, iterablei iterator mają określone znaczenia.

An iterable jest obiektem, który ma metodę __iter__, która zwraca iterator , lub która definiuje metodę __getitem__, która może przyjmować indeksy sekwencyjne począwszy od zera (i podnosi indeks IndexError gdy indeksy nie są już ważne). Więc iterable jest obiektem, z którego można uzyskać iterator.

Aniterator jest obiektem z metodą next (Python 2) lub __next__ (Python 3).

Za każdym razem, gdy używasz pętli for, lub map, lub rozumienia listy itp. w Pythonie metoda next jest wywoływana automatycznie, aby pobrać każdy element z iteratora , przechodząc przez proces iteracji .

Dobre miejsce do początek nauki to sekcja iteratorów w samouczku oraz sekcja typów iteratorów na stronie typów standardowych . Po zapoznaniu się z podstawami, wypróbuj sekcję iteratorów W HOWTO programowania funkcyjnego .

 401
Author: agf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-08 15:53:46

Oto Wyjaśnienie, którego używam w nauczaniu klas Pythona:

ITEROWALNY jest:

  • wszystko, co można zapętlić (np. można zapętlić nad łańcuchem znaków lub plikiem) lub
  • wszystko, co może pojawić się po prawej stronie pętli for: for x in iterable: ... lub
  • wszystko, co możesz wywołać za pomocą iter(), które zwróci ITERATOR: iter(obj) lub
  • obiekt, który definiuje __iter__, który zwraca nowy ITERATOR, lub może mieć metodę __getitem__ odpowiednią do indeksowania / align = "left" /

ITERATOR jest obiektem:

  • ze stanem, który pamięta, gdzie jest podczas iteracji,
  • metodą __next__, która:
    • zwraca następną wartość w iteracji
    • aktualizuje stan, aby wskazywał na następną wartość
    • sygnały, gdy odbywa się to przez podniesienie StopIteration
  • i jest to samo-iterowalne (co oznacza, że ma metodę __iter__, która zwraca self).

Uwagi:

  • The __next__ metoda w Pythonie 3 jest pisana next w Pythonie 2 i
  • wbudowana funkcja next() wywołuje tę metodę na przekazanym do niej obiekcie.

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
 266
Author: Raymond Hettinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-01 21:36:47

Powyższe odpowiedzi są świetne, ale jak większość z tego, co widziałem, nie podkreślaj rozróżnienia wystarczająco dla ludzi takich jak ja.

Ponadto, ludzie mają tendencję do "zbyt Pythonic", umieszczając definicje takie jak " X jest obiektem, który ma metodę __foo__()" przed. Takie definicje są poprawne - opierają się na filozofii kaczka-typowania, ale skupienie się na metodach ma tendencję do przechodzenia pomiędzy, gdy próbuje zrozumieć pojęcie w jego prostocie.

Więc dodaję swoją wersję.


W język naturalny,

  • Iteracja jest procesem pobierania jednego elementu na raz w rzędzie elementów.

W Pythonie,

  • Iterable jest obiektem, który jest, cóż, iterable, co po prostu oznacza, że może być używany w iteracji, np. z pętlą for. Jak? Za pomocą iteratora . Wyjaśnię poniżej.

  • ... iterator jest obiektem, który definiuje jak właściwie wykonać na iteracja -- konkretnie jaki jest następny element. Dlatego musi mieć next() metoda.

Iteratory same w sobie są również iteracyjne, z tą różnicą, że ich metoda __iter__() zwraca ten sam obiekt (self), niezależnie od tego, czy jego elementy zostały skonsumowane przez poprzednie wywołania next().


Więc co myśli interpreter Pythona, gdy widzi for x in obj: oświadczenie?

Look, a for loop. Wygląda jak praca dla iterator... Weźmy jedną. ... Jest taki obj facet, więc zapytajmy go.

"Panie obj, czy ma Pan swój iterator?" (... wywołania iter(obj), które wywołują obj.__iter__(), który szczęśliwie rozdaje lśniący nowy iterator _i.)

OK, to było łatwe... Zacznijmy więc iterację. (x = _i.next() ... x = _i.next()...)

Ponieważ Panu obj udało się w tym teście (mając pewną metodę zwracającą poprawny iterator), nagradzamy go przymiotnikiem: możesz teraz nazywać go " iterable Mr. obj".

Jednak, w prostych przypadkach, zwykle nie korzystasz z iteratora i iterable oddzielnie. Definiujesz więc tylko jeden obiekt , który jest również własnym iteratorem. (Pythona nie obchodzi to, że _i wręczony przez {[11] }nie był aż tak błyszczący, ale tylko obj sam.)

Dlatego w większości przykładów widziałem (i co było mylące mnie w kółko), można 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ą przypadki, jednak, kiedy możesz skorzystać z oddzielenia iteratora od iterable, 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ć oddzielne Iteratory dla obu. Lub wiele wątków ciągnących się z ogromnej listy: każdy może mieć swój własny iterator do przechodzenia przez wszystkie elementy. Zobacz @Raymond 's i @ glglgl' S odpowiedzi powyżej.

Wyobraź sobie, co możesz do:

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 iteracyjny . Iterator nie może być używany jako "źródło" w pętli for. Co for pętla przede wszystkim potrzebuje __iter__() (to zwraca coś z next()).

  • Oczywiście for nie jest jedyną pętlą iteracji, więc powyższe odnosi się do innych konstruuje również (while...).

  • Iterator {[5] } może rzucić Stopiterację, aby zatrzymać iterację. Nie musi, chociaż, to może iterować w nieskończoność lub użyć innych środków.

  • W powyższym "procesie myślowym" _i tak naprawdę nie istnieje. Wymyśliłem to imię.

  • Jest mała zmiana w Pythonie 3.x: next() metoda (nie wbudowana) teraz musi być nazywany __next__(). Tak, od początku tak powinno być.

  • Możesz również myśleć o tym w ten sposób: iterable ma dane, iterator ciągnie następny pozycja

Zastrzeżenie: nie jestem programista dowolnego interpretera Pythona, więc nie bardzo wiem, co interpreter "myśli". Powyższe rozważania są wyłącznie demonstracją tego, jak rozumiem temat z innych wyjaśnień, eksperymentów i rzeczywistych doświadczeń początkującego Pythona.

 84
Author: Alois Mahdal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:19

Iterable jest obiektem posiadającym metodę __iter__(). Może być wielokrotnie powtarzany, np. list() s I tuple() s.

Iterator jest obiektem, który iteruje. Jest zwracany metodą __iter__(), zwraca się za pomocą własnej metody __iter__() i ma metodę next() (__next__() W 3.x).

Iteracja jest procesem wywoływania tego next() resp. __next__() dopóki 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
 20
Author: glglgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-06 22:01:07

Nie wiem, czy to komuś pomaga, ale zawsze lubię wizualizować pojęcia w mojej głowie, aby lepiej je zrozumieć. Tak więc, jak mam małego synka, wizualizuję koncepcję iterable / iterator za pomocą klocków i białego papieru.

Przypuśćmy, że jesteśmy w ciemnym pokoju i na podłodze mamy Cegły dla mojego syna. Cegły o różnej wielkości, kolorze, nie ma teraz znaczenia. Załóżmy, że mamy 5 takich cegieł. Te 5 cegieł można opisać jako obiekt - powiedzmy zestaw cegieł. Możemy zrobić wiele rzeczy z tym zestawem cegieł - może wziąć jeden, a następnie wziąć drugi, a następnie trzeci, może zmienić miejsca cegieł, umieścić pierwszą cegłę nad drugim. Możemy z nimi robić wiele rzeczy. Dlatego ten zestaw cegieł jest iterowalnym obiektemlub sekwencją, ponieważ możemy przejść przez każdą cegłę i coś z nią zrobić. Możemy to robić tylko jak mój synek-możemy bawić się jedną cegłą na raz. Więc znowu wyobrażam sobie, że ten zestaw klocków ma być iterable . Pamiętaj, że jesteśmy w ciemnym pokoju. Albo prawie ciemno. Chodzi o to, że nie widzimy wyraźnie tych cegieł, jakiego koloru są, jaki kształt itp. Więc nawet jeśli chcemy coś z nimi zrobić-aka iterować przez nie - tak naprawdę nie wiemy co i jak, ponieważ jest zbyt ciemno.

To, co możemy zrobić, to blisko pierwszej cegły – jako element zestawu cegieł - możemy umieścić kawałek białego papieru fluorescencyjnego, aby zobaczyć, gdzie pierwszy brick-element is. I za każdym razem, gdy bierzemy cegłę z zestawu, zamieniamy białą kartkę papieru na następną cegłę, aby móc to zobaczyć w ciemnym pokoju. Ten biały kawałek papieru jest niczym więcej niż iteratorem . Jest to również obiekt . Ale obiekt z tym, co możemy pracować i bawić się z elementami naszego iterable object-bricks kit.

To przy okazji wyjaśnia mój wczesny błąd, gdy próbowałem następujące w bezczynności i dostał 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ł nasz zestaw klocków, ale nie biały kawałek 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. Gdyby ktoś mógł potwierdzić / poprawić wizualizację koncepcji, byłbym wdzięczny. To pomoże mi dowiedzieć się więcej.
 8
Author: Nikolay Dudaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 12:25:25

Oto moja ściąga:

 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...

  • każdy iterator jest iteracją?
  • metoda __iter__() obiektu kontenera może być zaimplementowana jako generator?
  • metoda iterable plus a __next__ niekoniecznie jest iteratorem?
 4
Author: AXO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 10:31:02

Nie wydaje mi się, aby można było uzyskać to znacznie prostsze niż Dokumentacja , jednak spróbuję:

  • Iterable jest czymś, co może byćiterated over. W praktyce zwykle oznacza sekwencję np. coś, co ma początek i koniec i jakiś sposób, aby przejść przez wszystkie elementy w nim.
  • Możesz myśleć Iterator jako pomocnicza pseudo-metoda (lub pseudo-atrybut), która daje (lub utrzymuje) następny (lub pierwszy) element w iterable . (W praktyce jest to tylko obiekt, który definiuje metodę next())

  • Iteracja jest prawdopodobnie najlepiej wyjaśniona przez definicję słowa Merriam-Webster :

B: powtarzanie sekwencji instrukcji komputerowych a określonych liczba razy lub do momentu spełnienia warunku-porównaj rekurencję

 3
Author: Kimvais,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-27 06:23:36
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

Więc,

  1. iterable jest obiektem, który może być zapętlony nad. np. list , string, tuple itp.

  2. Użycie funkcji iter na naszym obiekcie iterable zwróci obiekt iteracyjny .

  3. Teraz ten obiekt iterator ma metodę o nazwie __next__ (w Pythonie 3, lub po prostu next w Pythonie 2), dzięki której możesz uzyskać dostęp do każdego elementu iterable.

Więc, WYJŚCIE POWYŻSZEGO KODU BĘDZIE BE:

1

2

 1
Author: arpan kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 14:40:33

Przed zajęciem się iterable i iterator głównym czynnikiem decydującym o iterable i iterator jest sekwencja

Sekwencja: sekwencja jest zbiorem danych

Iterable: Iterable to obiekt typu sequence obsługujący metodę Iter.

Metoda Iter: metoda Iter przyjmuje sekwencję jako wejście i tworzy obiekt znany jako iterator

Iterator: Iterator to obiekt wywołujący następną metodę i przechodzący przez sekwencję.Na wywołanie następnego metoda zwraca obiekt, który aktualnie przemieścił.

Przykład:

x=[1,2,3,4]

X jest sekwencją, która składa się ze zbioru danych

y=iter(x)

Przy wywołaniu iter (x) zwraca iterator tylko wtedy, gdy obiekt x posiada metodę iter, w przeciwnym razie wywoła wyjątek.Jeśli zwraca iterator, to Y jest przypisane w następujący sposób:

y=[1,2,3,4]

Ponieważ y jest iteratorem, dlatego obsługuje metodę next ()

Przy wywołaniu metody next zwraca poszczególne elementy listy jeden przez jeden.

Po zwróceniu ostatniego elementu sekwencji, jeśli ponownie wywołamy następną metodę, spowoduje to błąd Stopiteracji

Przykład:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
 1
Author: Shadow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-28 09:04:07

Iterable: - coś, co jest iterable jest iterable; jak sekwencje, takie jak listy, ciągi itp. Posiada również metodę __getItem__() lub funkcję iter(), która zwraca iterator.

Iterator: - gdy otrzymamy obiekt iterator z metody iter() iterable; wywołujemy metodę __next__() (w python3) lub po prostu next() (w python2), aby uzyskać elementy jeden po drugim. Ta klasa lub instancja tej klasy jest nazywana iteratorem.

Od docs:-

Użycie iteratorów przenika i unifikuje 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 więcej elementów, __next__() podnosi wyjątek Stopiteracji, który nakazuje zakończenie pętli for. Metodę __next__() można wywołać za pomocą wbudowanej funkcji next(); 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 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
 1
Author: Vicrobot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 04:50:37

Iterable mają metodę __iter__, która tworzy instancję nowego iteratora za każdym razem.

Iteratory implementują metodę __next__, która zwraca poszczególne elementy, oraz metodę __iter__, która zwraca self.

Dlatego też Iteratory są również iteracyjne, ale iterable nie są iteratorami.

Luciano Ramalho, Biegły Pyton.
 0
Author: trthhrtz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 11:10:36

W Pythonie wszystko jest obiektem. Gdy mówi się, że obiekt jest iterowalny, oznacza to, że można przejść przez (np. iterację) obiekt jako zbiór.

Tablice na przykład są iteracyjne. Można przejść przez nie pętlą for i przejść od indeksu 0 do indeksu n, n jest długością obiektu tablicy minus 1.

Słowniki (pary klucz / wartość, zwane również tablicami asocjacyjnymi) są również iterowalne. Możesz przejść przez ich klucze.

Oczywiście obiekty, które są zbiory not nie są iterowalne. Na przykład obiekt bool ma tylko jedną wartość, True lub False. Nie jest iterable (to nie ma sensu, że jest iterable obiektu).

Czytaj więcej. http://www.lepus.org.uk/ref/companion/Iterator.xml

 -6
Author: user93097373,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-15 08:59:16