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]