Zoeken…


Iterator versus Iterable versus Generator

Een iterabel is een object dat een iterator kan retourneren. Elk object met status dat een __iter__ methode heeft en een iterator retourneert, is een iterabel. Het kan ook een object zonder status zijn dat een __getitem__ methode implementeert. - De methode kan indices gebruiken (beginnend vanaf nul) en een IndexError wanneer de indices niet langer geldig zijn.

De str klasse van Python is een voorbeeld van een __getitem__ __getitem__.

Een Iterator is een object dat de volgende waarde in een reeks produceert wanneer u next(*object*) op een object aanroept. Bovendien is elk object met een __next__ methode een iterator. Een iterator verhoogt StopIteration nadat de iterator is uitgeput en kan op dit moment niet opnieuw worden gebruikt.

Iterable klassen:

Iterabele klassen definiëren een __iter__ en een __next__ methode. Voorbeeld van een iterabele klasse:

class MyIterable:

    def __iter__(self):

         return self

    def __next__(self):
         #code

#Classic iterable object in older versions of python, __getitem__ is still supported...
class MySequence:

    def __getitem__(self, index):

         if (condition):
             raise IndexError
         return (item)

 #Can produce a plain `iterator` instance by using iter(MySequence())

Probeer de abstracte klasse uit de collections te instantiëren om dit beter te kunnen zien.

Voorbeeld:

Python 2.x 2.3
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
Python 3.x 3.0
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__

Ga als volgt te werk om Python 3-compatibiliteit voor iterabele klassen in Python 2 te verwerken:

Python 2.x 2.3
class MyIterable(object): #or collections.Iterator, which I'd recommend....

     ....

     def __iter__(self): 

          return self

     def next(self): #code

     __next__ = next

Beide zijn nu iterators en kunnen worden doorgelust:

ex1 = MyIterableClass()
ex2 = MySequence()

for (item) in (ex1): #code
for (item) in (ex2): #code

Generators zijn eenvoudige manieren om iterators te maken. Een generator is een iterator en een iterator is een iterator.

Wat kan iterabel zijn

Iterable kan alles zijn waarvoor items een voor een worden ontvangen , alleen doorsturen . Ingebouwde Python-collecties zijn iterabel:

[1, 2, 3]     # list, iterate over items
(1, 2, 3)     # tuple
{1, 2, 3}     # set
{1: 2, 3: 4}  # dict, iterate over keys

Generatoren retourneren iterables:

def foo():  # foo isn't iterable yet...
    yield 1

res = foo()  # ...but res already is

Herhaling over hele iterabel

s = {1, 2, 3}

# get every element in s
for a in s:
    print a  # prints 1, then 2, then 3

# copy into list
l1 = list(s)  # l1 = [1, 2, 3]

# use list comprehension
l2 = [a * 2 for a in s if a > 2]  # l2 = [6]

Controleer slechts één element in iterable

Gebruik uitpakken om het eerste element te extraheren en zorg ervoor dat dit de enige is:

a, = iterable

def foo():
    yield 1

a, = foo()  # a = 1

nums = [1, 2, 3]
a, = nums  # ValueError: too many values to unpack

Haal waarden een voor een uit

Begin met iter() ingebouwd om iterator over iterable te krijgen en gebruik next() om elementen een voor een te krijgen totdat StopIteration wordt weergegeven om het einde aan te geven:

s = {1, 2}   # or list or generator or even iterator
i = iter(s)  # get iterator
a = next(i)  # a = 1
b = next(i)  # b = 2
c = next(i)  # raises StopIteration

Iterator is niet terugkomend!

def gen():
    yield 1

iterable = gen()
for a in iterable:
    print a

# What was the first item of iterable? No way to get it now.
# Only to get a new iterator
gen()


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow