Python iterator, iterable

posloupnost

řetězec, unicode řetězec, seznam, n-tice, buffer, xrange. Všechno, co se dá rozložit na prvky - řetězec na znaky, seznamy na prvky, ...

iterator

proměnná, která může vzniknout z posloupnosti, a která může posloupnost procházet a pamatuje si, kde skončila. Něco jako "procházečka posloupností" ;-). Z posloupnosti vzniká funkcí iter():

>>> x=list("12321321321")
>>> x
['1', '2', '3', '2', '1', '3', '2', '1', '3', '2', '1']
>>> a=iter(x)
>>> a
<listiterator object at 0x011B7270>
>>> a.next()
'1'
>>> a.next()
'2'
>>>

zpětně z iterátoru můžete seznam získat opětovným použitím list(iterator).

iterátor nemusí vznikat jen z posloupností, může to být třída, která má metodu __iter__() a next(). Může to být i soubor:

>>> x=file("i:/lm.txt")
>>> x.next()
'Vážený zákazníku,\n'
>>> x.next()
'děkujeme Vám za Vaši objednávku.\n'
>>> x.next()
'\n'
>>> x.next()
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    x.next()
StopIteration
>>>

Python implicitně používá iterátory u příkazů for a if neco in necoJineho:

iterable

všechno, z čeho může vzniknout iterátor, všechno "procházení-schopné", tedy posloupnosti + třída, soubor, ...

Ako vytvoriť iterátor

Aby sme mohli z objektu nejakej triedy spraviť iterátor, musí obsahovať funkciu __iter__, ktorá vracia objekt, ktorý ma implementovanú funkciu __next__. Zvyčajne v jednej triede implementujeme obe funkcie, vtedy __iter__ vráti self, lebo v tej triede máme implementovanú funkciu __next__. Ak chceme, aby iterátor nevracal už ďalšie prvky, vyhodíme výnimku StopIteration?

class TestIteratora:
    "Iterator, ktory generuje cisla."
    def __init__(self, hornaHranica):
        self.i = 0
        self.hornaHranica = hornaHranica
    def __iter__(self):
        return self
    def __next__(self):
        if self.i == self.hornaHranica:
            raise StopIteration
        self.i += 1
        return self.i

a = TestIteratora(5)
print(next(a))
#  1
print(next(a))
#  2
for i in TestIteratora(3):  # iterator mozno prechadzat for cyklom
    print(i)
# 1
# 2
# 3
b = list(TestIteratora(3)) # z prvkov iteratora mozeme urobit zoznam
print(b)
# [1,2,3]