Python Iteratorer (__iter__ og __next__): Hvordan bruges det og hvorfor?

Iteratorer er genstande, der kan gentages. I denne vejledning lærer du, hvordan iterator fungerer, og hvordan du kan opbygge din egen iterator ved hjælp af __iter__ og __next__ metoder.

Video: Python Iteratorer

Iteratorer i Python

Iteratorer er overalt i Python. De er elegant implementeret i forsløjfer, forståelser, generatorer osv., Men er skjult i almindeligt syn.

Iterator i Python er simpelthen et objekt, der kan gentages. Et objekt, der returnerer data, et element ad gangen.

Teknisk set skal et Python iterator-objekt implementere to specielle metoder __iter__()og __next__()kaldes samlet iteratorprotokollen .

Et objekt kaldes iterabelt, hvis vi kan få en iterator fra det. De fleste indbyggede containere i Python som: liste, tuple, streng osv. Kan gentages.

Den iter()funktion (som igen kalder __iter__()metoden) returnerer en iterator fra dem.

Iterering gennem en Iterator

Vi bruger next()funktionen til manuelt at gentage alle emner i en iterator. Når vi når slutningen, og der ikke er flere data, der skal returneres, hæver det StopIterationundtagelsen. Følgende er et eksempel.

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

Produktion

 4 7 0 3 Traceback (seneste opkald sidst): Fil "", linje 24, i næste (my_iter) StopIteration

En mere elegant måde til automatisk iterering er ved hjælp af for-sløjfen. Ved hjælp af dette kan vi gentage over ethvert objekt, der kan returnere en iterator, for eksempel liste, streng, fil osv.

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

Arbejde med for loop til Iteratorer

Som vi ser i eksemplet ovenfor, kunne forsløjfen automatisk gentage sig gennem listen.

Faktisk kan forsløjfen gentage sig over enhver iterabel. Lad os se nærmere på, hvordan forsløjfen faktisk implementeres i Python.

 for element in iterable: # do something with element

Implementeres faktisk som.

 # 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

Så internt foropretter sløjfen et iteratorobjekt iter_objved at kalde iter()på iterablen.

Ironisk nok er denne forsløjfe faktisk en uendelig mens løkke.

Inde i sløjfen kalder det for next()at få det næste element og udfører forsløjfens krop med denne værdi. Når alle genstande er udstødt, StopIterationhæves der, som fanges internt, og løkken slutter. Bemærk, at enhver anden form for undtagelse vil passere.

Bygger brugerdefinerede itatorer

At bygge en iterator fra bunden er let i Python. Vi skal bare implementere __iter__()og __next__()metoderne.

Den __iter__()metode returnerer iterator objektet selv. Om nødvendigt kan der foretages en vis initialisering.

Den __next__()metode skal returnere det næste element i sekvensen. Når den når slutningen og i efterfølgende opkald, skal den hæve StopIteration.

Her viser vi et eksempel, der giver os den næste styrke på 2 i hver iteration. Power exponent starter fra nul op til et brugersætnummer.

Hvis du ikke har nogen idé om objektorienteret programmering, skal du besøge 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))

Produktion

 1 2 4 8 Traceback (seneste opkald sidst): File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in print (next (i)) File "", line 18, in __next__ raise StopIteration StopIteration

Vi kan også bruge en forløkke til at gentage vores klasse iterator.

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

Python Infinite Iteratorer

Det er ikke nødvendigt, at genstanden i et iteratorobjekt skal være opbrugt. Der kan være uendelige iteratorer (som aldrig ender). Vi skal være forsigtige, når vi håndterer sådanne iteratorer.

Her er et simpelt eksempel for at demonstrere uendelige iteratorer.

Den indbyggede iter()funktionsfunktion kan kaldes med to argumenter, hvor det første argument skal være et objekt, der kan kaldes (funktion) og det andet er vagtpost. Iteratoren kalder denne funktion, indtil den returnerede værdi er lig med vagtpost.

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

Vi kan se, at int()funktionen altid returnerer 0. Så ved at sende den som iter(int,1)vil returnere en iterator, der ringer, int()indtil den returnerede værdi er lig med 1. Dette sker aldrig, og vi får en uendelig iterator.

Vi kan også bygge vores egne uendelige iteratorer. Den følgende iterator returnerer teoretisk alle de ulige tal.

 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

En prøvekørsel ville være som følger.

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

Og så videre…

Vær omhyggelig med at medtage en afsluttende tilstand, når du gentager over disse typer af uendelige iteratorer.

Fordelen ved at bruge iteratorer er, at de sparer ressourcer. Som vist ovenfor kunne vi få alle de ulige numre uden at gemme hele nummersystemet i hukommelsen. Vi kan have uendelige ting (teoretisk set) i en begrænset hukommelse.

Der er en lettere måde at oprette iteratorer på i Python. For at lære mere besøg: Python-generatorer ved hjælp af udbytte.

Interessante artikler...