Python-iteraattorit (__iter__ ja __next__): Kuinka sitä käytetään ja miksi?

Iteraattorit ovat esineitä, joista voidaan toistaa. Tässä opetusohjelmassa opit, kuinka iteraattori toimii ja kuinka voit rakentaa oman iteraattorin __iter__- ja __next__ -menetelmillä.

Video: Python Iterators

Iteraattorit Pythonissa

Iteraattorit ovat kaikkialla Pythonissa. Ne toteutetaan tyylikkäästi forsilmukoissa, ymmärryksissä, generaattoreissa jne., Mutta ne ovat piilossa näkyvissä.

Iterator Pythonissa on yksinkertaisesti objekti, josta voidaan toistaa. Objekti, joka palauttaa tietoja, yksi elementti kerrallaan.

Teknisesti katsottuna Python- iteraattoriobjektin on toteutettava kaksi erityistä menetelmää, __iter__()ja sitä __next__()kutsutaan yhdessä iteraattoriprotokollaksi .

Objektia kutsutaan iteroitavaksi, jos voimme saada siitä iteraattorin. Useimmat Pythonin sisäiset säilöt, kuten: luettelo, dupleksi, merkkijono jne., Ovat iterable.

iter()Toiminto (joka puolestaan kutsuu __iter__()menetelmä) palauttaa iteraattorin niistä.

Iteroituminen iteraattorin kautta

Käytämme next()toimintoa iteroimaan manuaalisesti kaikki iteraattorin kohteet. Kun pääsemme loppuun ja ei enää ole palautettavia tietoja, se herättää StopIterationpoikkeuksen. Seuraava on esimerkki.

 # 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)

Tuotos

 4 7 0 3 Seuranta (viimeisin puhelu viimeisin): Tiedosto "", rivi 24, seuraavassa (my_iter) StopIteration

Tyylikkäämpi tapa iteroida automaattisesti on for for -silmukka. Tämän avulla voimme toistaa minkä tahansa objektin, joka voi palauttaa iteraattorin, esimerkiksi luettelon, merkkijonon, tiedoston jne.

 >>> for element in my_list:… print(element)… 4 7 0 3

Työskentely silmukalle iteraattoreille

Kuten näemme edellisestä esimerkistä, forsilmukka pystyi iteroimaan automaattisesti luettelon läpi.

Itse asiassa forsilmukka voi toistaa minkä tahansa toistettavan. Katsotaanpa tarkemmin, miten forsilmukka todella toteutetaan Pythonissa.

 for element in iterable: # do something with element

On tosiasiallisesti toteutettu.

 # 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

Joten sisäisesti forsilmukka luo iteraattoriobjektin iter_objkutsumalla iter()iteroitavaa.

Ironista kyllä, tämä forsilmukka on itse asiassa ääretön, kun taas silmukka.

Silmukan sisällä se kutsuu next()saamaan seuraavan elementin ja suorittaa forsilmukan rungon tällä arvolla. Kun kaikki tavarat ovat poistuneet, StopIterationnostetaan, joka tarttuu sisäisesti ja silmukka päättyy. Huomaa, että mikä tahansa muu poikkeus kulkee läpi.

Mukautettujen iteraattorien rakentaminen

Iteraattorin rakentaminen tyhjästä on helppoa Pythonissa. Meidän on vain toteutettava __iter__()ja __next__()menetelmät.

__iter__()Menetelmä palauttaa iteraattoria objektin itse. Tarvittaessa voidaan suorittaa alustus.

__next__()Menetelmä tulee palauttaa seuraavaan kohteeseen järjestyksessä. Päättyessään ja myöhemmissä puheluissa sen on nostettava StopIteration.

Tässä näytetään esimerkki, joka antaa meille seuraavan 2: n voiman jokaisessa iteraatiossa. Tehoeksponentti alkaa nollasta käyttäjän asetettuun numeroon.

Jos sinulla ei ole aavistustakaan kohdennetusta ohjelmoinnista, käy Python Object-Oriented Programming -ohjelmassa.

 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))

Tuotos

 1 2 4 8 Jäljitys (viimeisin puhelu viimeisin): Tiedosto "/home/bsoyuj/Desktop/Untitled-1.py", rivi 32, tulostettuna (seuraava (i) tiedosto "", rivi 18, __next__: ssa _ nosta StopIteration StopIteration

Voimme myös käyttää forsilmukkaa iteroimalla iteraattoriluokkamme.

 >>> for i in PowTwo(5):… print(i)… 1 2 4 8 16 32

Python Infinite Iterators

Ei ole välttämätöntä, että iteraattorikohteen alkio on tyhjennettävä. Iteraattoreita voi olla ääretön (joka ei koskaan pääty). Meidän on oltava varovaisia ​​käsitellessäsi tällaisia ​​iteraattoreita.

Tässä on yksinkertainen esimerkki loputtomien iteraattorien esittelystä.

Sisäänrakennettu iter()funktiofunktio voidaan kutsua kahdella argumentilla, joissa ensimmäisen argumentin on oltava kutsuva objekti (funktio) ja toinen on vartija. Iteraattori kutsuu tätä toimintoa, kunnes palautettu arvo on yhtä suuri kuin vartija.

 >>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0

Voimme nähdä, että int()funktio palauttaa aina 0. Joten sen välittäminen iter(int,1)palauttaa iteraattorin, joka kutsuu, int()kunnes palautettu arvo on yhtä kuin 1. Tätä ei koskaan tapahdu ja saamme loputon iteraattori.

Voimme myös rakentaa omia loputtomia iteraattoreita. Seuraava iteraattori palauttaa teoriassa kaikki parittomat luvut.

 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

Näyte ajo olisi seuraava.

 >>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7

Ja niin edelleen…

Ole varovainen sisällyttää lopetustila, kun iteroidaan tämäntyyppisten äärettömien iteraattoreiden yli.

Iteraattoreiden käytön etuna on, että ne säästävät resursseja. Kuten yllä on esitetty, saisimme kaikki parittomat numerot tallentamatta koko numerojärjestelmää muistiin. Meillä voi olla äärettömiä kohteita (teoreettisesti) rajallisessa muistissa.

On helpompi tapa luoda iteraattoreita Pythonissa. Lisätietoja on osoitteessa: Python-generaattorit tuottoa käyttämällä.

Mielenkiintoisia artikkeleita...