Iteraatorid on objektid, mida saab korrata. Selles õpetuses saate teada, kuidas iteraator töötab ja kuidas saate oma iteraatori üles ehitada meetodite __iter__ ja __next__ abil.
Video: Pythoni iteraatorid
Iteraatorid Pythonis
Iteraatorid on Pythonis kõikjal. Neid rakendatakse elegantselt for
silmuste, arusaamade, generaatorite jms sees, kuid need on silmapiiril peidetud.
Iterator Pythonis on lihtsalt objekt, mida saab korrata. Objekt, mis tagastab andmed üks element korraga.
Tehniliselt öeldes, Python iteraatoris objekti peab rakendama kaks spetsiaalseid meetodeid, __iter__()
ja __next__()
ühiselt nimetatakse iteraatoris protokolli .
Objekti nimetatakse korduvaks, kui saame sellest iteraatori. Enamik Pythoni sisseehitatud konteinereid on näiteks: loend, dupleks, string jne.
iter()
Funktsioon (mis omakorda nõuab __iter__()
meetod) tagastab iteraatoris neilt.
Korduv iteraatori kaudu
Kasutame next()
funktsiooni iteraatori kõigi üksuste käsitsi itereerimiseks. Kui jõuame lõpuni ja enam pole andmeid, mida tagastada, tõstab see StopIteration
Erandit. Järgnev on näide.
# 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äljund
4 7 0 3 Jälgimine (viimane kõne on viimane): fail "", rida 24, järgmisel (my_iter) StopIteration
Elegantsem viis automaatseks kordamiseks on for loopi kasutamine. Selle abil saame iteratsiooni teha mis tahes objekti puhul, mis võib iteraatori tagastada, näiteks loendi, stringi, faili jne.
>>> for element in my_list:… print(element)… 4 7 0 3
Iteraatorite jaoks silmuse töötamine
Nagu näeme ülaltoodud näites, suutis for
silmus loendi kaudu automaatselt korduda.
Tegelikult saab for
tsükkel korduda mis tahes korduvana. Vaatame lähemalt, kuidas for
silmus Pythonis tegelikult rakendub.
for element in iterable: # do something with element
Rakendatakse tegelikult kui.
# 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
Niisiis for
loob tsükkel iteraatori objekti, iter_obj
kutsudes iter()
iterable'i.
Irooniline, et see for
silmus on tegelikult lõpmatu kui silmus.
Silmuse sees kutsub next()
see järgmise elemendi saamiseks ja käivitab for
selle väärtusega silmuse keha . Pärast kõigi esemete väljalaskmist StopIteration
tõuseb sisemine kinni ja silmus lõpeb. Pange tähele, et muud liiki erandid lähevad läbi.
Kohandatud iteraatorite ehitamine
Iteraatori nullist üles ehitamine on Pythonis lihtne. Peame lihtsalt rakendama __iter__()
ja __next__()
meetodid.
__iter__()
Meetod tagastab iteraatoris objekt ise. Vajadusel saab mõningaid lähtestusi teha.
__next__()
Meetod peab tagastama järgmise üksuse järjestus. Lõpule jõudes ja järgmistes kõnedes peab see tõsta StopIteration
.
Siinkohal näitame näidet, mis annab meile järgmise korduse 2 igas korduses. Võimsuse eksponent algab nullist kuni kasutaja määratud numbrini.
Kui teil pole aimugi objektorienteeritud programmeerimise kohta, külastage Pythoni objektorienteeritud programmeerimist.
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äljund
1 2 4 8 Jälgimine (viimane kõne viimati): fail "/home/bsoyuj/Desktop/Untitled-1.py", rida 32, prindituna (järgmine (i)) fail "", rida 18, __next__-s __next__ tõstke StopIteration StopIteration
Samuti võime kasutada for
tsüklit iteratsiooniklassi kordamiseks.
>>> for i in PowTwo(5):… print(i)… 1 2 4 8 16 32
Pythoni lõpmatud itaatorid
Pole vaja, et iteraatoriobjektis olev üksus peaks olema ammendatud. Võib olla lõpmatuid kordajaid (mis ei lõpe kunagi). Selliste iteraatorite käsitlemisel peame olema ettevaatlikud.
Siin on lihtne näide, et näidata lõpmatuid kordajaid.
Sisseehitatud funktsiooni iter()
funktsiooni saab kutsuda kahe argumendiga, kus esimene argument peab olema helistatav objekt (funktsioon) ja teine on valvur. Kordaja kutsub seda funktsiooni seni, kuni tagastatav väärtus on võrdne valvuriga.
>>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0
Näeme, et int()
funktsioon tagastab alati 0. Nii et selle edastamine iter(int,1)
tagastab iteraatori, mis kutsub, int()
kuni tagastatav väärtus on võrdne 1. Seda ei juhtu kunagi ja saame lõpmatu iteraatori.
Saame ehitada ka oma lõpmatud kordajad. Järgmine iteraator tagastab teoreetiliselt kõik paaratud arvud.
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
Proovijooks oleks järgmine.
>>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7
Ja nii edasi…
Seda tüüpi lõpmatute iteraatorite kordamisel olge ettevaatlik.
Iteraatorite kasutamise eeliseks on see, et need säästavad ressursse. Nagu ülalpool näidatud, võiksime kõik paarituid numbreid hankida, ilma et kogu arvusüsteem mällu salvestuks. Piiratud mälus võib meil olla (teoreetiliselt) lõpmatuid üksusi.
Pythonis on iteraatorite loomiseks lihtsam viis. Lisateabe saamiseks külastage saiti Python generaatorid.