Python Language
Iterables och Iterators
Sök…
Iterator vs Iterable vs Generator
En iterable är ett objekt som kan returnera en iterator . Alla objekt med tillstånd som har en __iter__
metod och returnerar en iterator är en iterbar. Det kan också vara ett objekt utan tillstånd som implementerar en __getitem__
metod. - Metoden kan ta index (från noll) och höja ett IndexError
när indexen inte längre är giltiga.
Pythons str
klass är ett exempel på en __getitem__
__-iterbar.
En Iterator är ett objekt som producerar nästa värde i en sekvens när du ringer next(*object*)
på något objekt. Dessutom är alla objekt med en __next__
metod en iterator. En iterator höjer StopIteration
efter uttömning av iteratorn och kan inte återanvändas vid denna punkt.
Iterable klasser:
Iterable klasser definierar en __iter__
och en __next__
metod. Exempel på en iterbar klass:
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())
Försöker initiera den abstrakta klassen från collections
modul för att bättre se detta.
Exempel:
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__
Hantera Python 3-kompatibilitet för iterable klasser i Python 2 genom att göra följande:
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def __iter__(self):
return self
def next(self): #code
__next__ = next
Båda dessa är nu iteratorer och kan slingas igenom:
ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code
Generatorer är enkla sätt att skapa iteratorer. En generator är en iterator och en iterator är en iterbar.
Vad kan vara iterable
Iterable kan vara allt för vilket artiklar tas emot en efter en, bara framåt . Inbyggda Python-kollektioner är iterable:
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
Generatorer returnerar iterables:
def foo(): # foo isn't iterable yet...
yield 1
res = foo() # ...but res already is
Iterating över hela iterable
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]
Verifiera bara ett element i iterable
Använd packning för att extrahera det första elementet och se till att det är det enda:
a, = iterable
def foo():
yield 1
a, = foo() # a = 1
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
Extrahera värdena en efter en
Börja med iter()
inbyggd för att få iterator över iterable och använd next()
att få element en efter en tills StopIteration
är upphöjd vilket betyder slutet:
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 är inte reentrant!
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()