Iterátory sú objekty, ktoré je možné iterovať. V tomto tutoriáli sa dozviete, ako iterátor funguje a ako si môžete vytvoriť svoj vlastný iterátor pomocou metód __iter__ a __next__.
Video: Pythonové iterátory
Iterátory v Pythone
Iterátory sú všade v Pythone. Elegantne sú implementované v rámci for
slučiek, porozumení, generátorov atď., Ale sú skryté na očiach.
Iterátor v Pythone je jednoducho objekt, ktorý je možné iterovať. Objekt, ktorý vráti údaje, jeden prvok po druhom.
Technicky vzaté, Python iterátor objekt musí implementovať dve špeciálne metódy, __iter__()
a __next__()
, kolektívne nazvaný Iterator protokol .
Objekt sa nazýva iterovateľný, ak z neho môžeme získať iterátor. Väčšina vstavaných kontajnerov v Pythone ako: list, n-tica, reťazec atď. Sú iterovateľné.
iter()
Funkcia (ktorá zase volá __iter__()
metódu) vracia iterátor z nich.
Iterácia Iterátorom
Pomocou tejto next()
funkcie manuálne iterujeme všetky položky iterátora. Keď dôjdeme na koniec a už nebudeme musieť vrátiť žiadne údaje, vyvolá to StopIteration
výnimku. Nasleduje príklad.
# define a list my_list = (4, 7, 0, 3) # get an iterator using iter() my_iter = iter(my_list) # iterate through it using next() # Output: 4 print(next(my_iter)) # Output: 7 print(next(my_iter)) # next(obj) is same as obj.__next__() # Output: 0 print(my_iter.__next__()) # Output: 3 print(my_iter.__next__()) # This will raise error, no items left next(my_iter)
Výkon
4 7 0 3 Traceback (posledný posledný hovor): súbor „“, riadok 24, v nasledujúcej (my_iter) StopIteration
Elegantnejším spôsobom automatickej iterácie je použitie cyklu for. Pomocou toho môžeme iterovať akýkoľvek objekt, ktorý dokáže vrátiť iterátor, napríklad zoznam, reťazec, súbor atď.
>>> for element in my_list:… print(element)… 4 7 0 3
Práca cyklu for pre iterátory
Ako vidíme vo vyššie uvedenom príklade, for
slučka bola schopná automaticky iterovať zoznamom.
V skutočnosti môže for
slučka iterovať cez ktorúkoľvek opakovateľnú položku. Pozrime sa podrobnejšie na to, ako je for
slučka v Pythone skutočne implementovaná.
for element in iterable: # do something with element
Je skutočne implementovaný ako.
# create an iterator object from that iterable iter_obj = iter(iterable) # infinite loop while True: try: # get the next item element = next(iter_obj) # do something with element except StopIteration: # if StopIteration is raised, break from loop break
Takže vnútorne for
slučka vytvára iterátorový objekt iter_obj
vyvolaním iter()
iterovateľného objektu.
Je iróniou, že táto for
slučka je vlastne nekonečná while slučka.
Vo vnútri slučky volá, next()
aby získal ďalší prvok, a vykoná telo for
slučky s touto hodnotou. Potom, čo sa všetky položky vyčerpajú, StopIteration
sa zdvihne, čo je vnútorne zachytené a slučka končí. Upozorňujeme, že prejde akýkoľvek iný druh výnimky.
Budovanie vlastných iterátorov
Vytvorenie iterátora od nuly je v Pythone ľahké. Len musíme implementovať __iter__()
aj na __next__()
metódy.
__iter__()
Metóda vracia objekt Iterator sám. V prípade potreby je možné vykonať určitú inicializáciu.
__next__()
Metóda musí vrátiť ďalšiu položku v poradí. Po dosiahnutí konca a v ďalších výzvach sa musí zvýšiť StopIteration
.
Tu ukážeme príklad, ktorý nám dá ďalšiu mocninu 2 v každej iterácii. Silový exponent začína od nuly po číslo nastavené používateľom.
Pokiaľ nemáte predstavu o objektovo orientovanom programovaní, navštívte Python Object-Oriented Programming.
class PowTwo: """Class to implement an iterator of powers of two""" def __init__(self, max=0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration # create an object numbers = PowTwo(3) # create an iterable from the object i = iter(numbers) # Using next to get to the next iterator element print(next(i)) print(next(i)) print(next(i)) print(next(i)) print(next(i))
Výkon
1 2 4 8 Traceback (posledný hovor naposledy): Súbor "/home/bsoyuj/Desktop/Untitled-1.py", riadok 32, v tlačenej podobe (ďalší (i)) Súbor "", riadok 18, v __next__ zvýšiť StopIteration StopIterácia
Môžeme tiež použiť for
slučku na iteráciu nad našou triedou iterátorov.
>>> for i in PowTwo(5):… print(i)… 1 2 4 8 16 32
Python nekonečné iterátory
Nie je potrebné, aby sa položka v iteračnom objekte musela vyčerpať. Môže existovať nekonečné množstvo iterátorov (ktoré nikdy nekončia). Pri manipulácii s takýmito iterátormi musíme byť opatrní.
Tu je jednoduchý príklad na demonštráciu nekonečných iterátorov.
Funkciu vstavanej iter()
funkcie je možné volať pomocou dvoch argumentov, kde prvý argument musí byť volaný objekt (funkcia) a druhý je sentinel. Iterátor volá túto funkciu, kým sa vrátená hodnota nerovná sentinelu.
>>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0
Vidíme, že int()
funkcia vždy vráti 0. Takže jej odovzdaním ako iter(int,1)
vrátime iterátor, ktorý volá, int()
kým sa vrátená hodnota nebude rovnať 1. Toto sa nikdy nestane a dostaneme nekonečný iterátor.
Môžeme si tiež zostaviť vlastné nekonečné iterátory. Nasledujúci iterátor teoreticky vráti všetky nepárne čísla.
class InfIter: """Infinite iterator to return all odd numbers""" def __iter__(self): self.num = 1 return self def __next__(self): num = self.num self.num += 2 return num
Ukážka cyklu by bola nasledovná.
>>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7
A tak ďalej…
Pri iterácii nad týmito typmi nekonečných iterátorov buďte opatrní.
Výhodou používania iterátorov je, že šetria zdroje. Ako je uvedené vyššie, mohli by sme získať všetky nepárne čísla bez toho, aby sme uložili celý číselný systém do pamäte. V konečnej pamäti môžeme mať (teoreticky) nekonečné položky.
Existuje jednoduchší spôsob, ako vytvoriť iterátory v Pythone. Ak sa chcete dozvedieť viac, navštívte: Generátory Pythonu využívajúce výnos.