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]