Edit detail for IteratorIterable revision 5 of 1

5
Editor: manduch
Time: 2010/08/23 13:11:20 GMT+2
Note:

changed:
-
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]


záložky
--------
- http://docs.python.org/lib/types.html
- http://docs.python.org/lib/typeiter.html


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]