Python Iteratorji (__iter__ in __next__): Kako ga uporabiti in zakaj?

Ponavljalci so predmeti, ki jih je mogoče ponoviti. V tej vadnici boste izvedeli, kako deluje iterator in kako lahko z uporabo metod __iter__ in __next__ ustvarite svoj iterator.

Video: Python Iterators

Iteratorji v Pythonu

Iteratorji so povsod v Pythonu. Elegantno se izvajajo v forzankah, razumevanjih, generatorjih itd., Vendar so skriti pred očmi.

Iterator v Pythonu je preprosto predmet, ki ga je mogoče ponoviti. Predmet, ki bo vrnil podatke, po en element.

Tehnično gledano mora objekt iteratorja Python izvajati dve posebni metodi __iter__()in __next__()skupaj imenovan protokol iteratorja .

Predmet se imenuje iterable, če lahko od njega dobimo iterator. Večina vgrajenih vsebnikov v Pythonu, kot so: seznam, nabor, niz itd., Je iterabil.

iter()Funkcija (ki pa terja __iter__()način) vrne iterator od njih.

Ponavljanje skozi iterator

Bomo uporabili next()funkcijo za ponovitev ročno skozi vse postavke iteratorja. Ko pridemo do konca in ni več podatkov, ki jih je treba vrniti, se bo pojavila StopIterationizjema. Sledi primer.

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

Izhod

 4 7 0 3 Traceback (zadnji zadnji klic): Datoteka "", vrstica 24, v naslednjem (my_iter) StopIteration

Elegantnejši način samodejnega ponavljanja je uporaba zanke for. S tem lahko ponovimo kateri koli predmet, ki lahko vrne iterator, na primer seznam, niz, datoteko itd.

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

Delo zanke for za iteratorje

Kot vidimo v zgornjem primeru, se je forzanka lahko samodejno ponavljala po seznamu.

Pravzaprav se forzanka lahko ponovi nad katerim koli ponovljivim. Poglejmo si podrobneje, kako se forzanka dejansko izvaja v Pythonu.

 for element in iterable: # do something with element

Se dejansko izvaja kot.

 # 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

Tako interno forzanka ustvari objekt iteratorja, iter_objtako da pokliče iter()iterable.

Ironično je, da je ta forzanka pravzaprav neskončna zanka while.

Znotraj zanke pokliče, next()da dobi naslednji element, in izvrši telo forzanke s to vrednostjo. Ko se vsi predmeti izpuhnejo, StopIterationse dvigne, ki se notranje ujame in zanka konča. Upoštevajte, da se bodo prenesle vse druge vrste izjem.

Izdelava iteratorjev po meri

V Pythonu je preprosto ustvariti iterator iz nič. Samo uporabiti moramo metode __iter__()in __next__()metode.

__iter__()Metoda vrne iterator sam predmet. Po potrebi se lahko izvede nekaj inicializacije.

__next__()Metoda mora vrniti naslednji element v zaporedju. Ko pride do konca in v naslednjih klicih, se mora dvigniti StopIteration.

Tukaj prikazujemo primer, ki nam bo dal naslednjo moč 2 v vsaki ponovitvi. Kazalnik moči se začne od nič do uporabniško nastavljene številke.

Če o objektno usmerjenem programiranju nimate pojma, obiščite Python objektno usmerjeno programiranje.

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

Izhod

 1 2 4 8 Sledenje (zadnji zadnji klic): Datoteka "/home/bsoyuj/Desktop/Untitled-1.py", vrstica 32, v tisku (naslednja (i)) Datoteka "", vrstica 18, v __next__ dvig StopIteration StopIteration

Z forzanko lahko uporabimo tudi za iteracijo nad našim razredom iteratorjev.

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

Python Infinite Iterators

Ni nujno, da je element v predmetu iteratorja izčrpan. Obstajajo lahko neskončni iteratorji (ki se nikoli ne končajo). Pri ravnanju s takimi ponovitvami moramo biti previdni.

Tu je preprost primer za prikaz neskončnih iteratorjev.

Vgrajeno funkcijsko iter()funkcijo lahko pokličete z dvema argumentoma, pri čemer mora biti prvi argument predmet, ki ga je mogoče klicati (funkcija), drugi pa je stražnik. Iterator pokliče to funkcijo, dokler vrnjena vrednost ni enaka kontrolnemu.

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

Vidimo lahko, da int()funkcija vedno vrne 0. Torej, če jo posredujete, iter(int,1)bo vrnil iterator, ki pokliče, int()dokler vrnjena vrednost ni enaka 1. To se nikoli ne zgodi in dobimo neskončen iterator.

Lahko si izdelamo tudi lastne neskončne ponovitve. Naslednji iterator bo teoretično vrnil vsa neparna števila.

 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

Vzorec bi bil naslednji.

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

In tako naprej…

Bodite previdni, da vključite zaključni pogoj, kadar ponavljate te vrste neskončnih ponoviteljev.

Prednost uporabe iteratorjev je v tem, da prihranijo vire. Kot je prikazano zgoraj, smo lahko dobili vse lihe številke, ne da bi v pomnilnik shranili celoten številski sistem. V končnem spominu imamo lahko (teoretično) neskončne predmete.

Obstaja enostavnejši način za ustvarjanje iteratorjev v Pythonu. Če želite izvedeti več, obiščite: Generatorji Pythona z uporabo yield.

Zanimive Članki...