Gli iteratori Python sono oggetti nativi con una quantità cal­co­la­bi­le di elementi che im­ple­men­ta­no il pro­to­col­lo degli iteratori co­sti­tui­to dalle due funzioni iter() e next().

Cosa sono esat­ta­men­te gli iteratori Python?

Gli iteratori Python sono in­nan­zi­tut­to una forma speciale di oggetti Python. Si con­trad­di­stin­guo­no per essere composti da una serie di elementi con­teg­gia­bi­li. Per­met­to­no quindi di contare gli elementi di un iteratore e di iterare su tutti gli elementi di un iteratore Python.

Consiglio

Python è un ec­cel­len­te lin­guag­gio di pro­gram­ma­zio­ne per i progetti web. Deploy Now, grazie alla com­pi­la­zio­ne e alla di­stri­bu­zio­ne au­to­ma­ti­ca tramite GitHub, vi fornisce supporto per i vostri progetti internet, così avete sempre tutto sotto controllo.

Iteratori e iterabili

Anche se sono stret­ta­men­te correlati fra loro, gli iteratori e gli iterabili Python non devono essere confusi. I diversi iterabili come la lista Python si con­trad­di­stin­guo­no per il metodo iter(), che permette l’ite­ra­zio­ne su di essi. La regola generale è che tutto ciò che si trova sul lato destro dell’in­te­sta­zio­ne del ciclo quando si chiama un ciclo for è un iterabile.

l = [1, 2, 3]
for x in l:
	print(x)
Python

Come potete vedere, chiamando il ciclo for in Python la lista inserita nella variabile “l” compare nella parte destra dell’in­te­sta­zio­ne del ciclo dopo la parola chiave “in”, pertanto è un iterabile.

Da un iterabile potete derivare un iteratore Python. Di seguito vi ri­por­tia­mo un esempio di codice per chiarire e mostrare le dif­fe­ren­ze:

string = "test"
iteratorobject = iter(string)
next(iteratorobject)
iter(iteratorobject)
Python

Per prima cosa nel codice viene inserita una stringa Python con il valore “test” nella variabile chiamata “string”. Anche le stringhe rientrano nella categoria degli iterabili, perché possono iterare su ciascuna lettera della stringa.

Poter iterare sulle stringhe non significa nient’altro che una stringa supporta anche la funzione iter(). Lo vedete anche nella riga di codice suc­ces­si­va, in cui creiamo un iteratore Python per chiamare la funzione iter insieme alla stringa pre­ce­den­te­men­te creata. Viene re­sti­tui­to un puntatore nelle stringhe, che viene salvato nella variabile chiamata “ite­ra­to­ro­b­ject”. L’iteratore Python si trova quindi in uno stato che possiamo mo­di­fi­ca­re chiamando il metodo next() sull’iteratore Python. Fa in modo che il puntatore sia spostato di un carattere, in modo che “ite­ra­to­ro­b­ject” dopo la chiamata di funzione punti sulla prima lettera della stringa.

La chiamata di funzione di iter(), che come parametro di tra­sfe­ri­men­to riceve l’iteratore Python, re­sti­tui­sce un ri­fe­ri­men­to sullo stesso. Gli iteratori Python sono dunque auto-iterabili.

Iteratori e ge­ne­ra­to­ri

È im­por­tan­te anche di­stin­gue­re gli iteratori dai ge­ne­ra­to­ri Python. Ciascun ge­ne­ra­to­re Python è anche un iteratore, ma non viceversa. A dif­fe­ren­za di un ge­ne­ra­to­re, un iteratore non è formato ne­ces­sa­ria­men­te con una funzione che contiene un’espres­sio­ne yield.

Consiglio

Gli iteratori Python sono un costrutto di programma piuttosto avanzato, non trattato da tutti i tutorial di Python. Se volete conoscere aspetti avanzati di Python, vi con­si­glia­mo gli articoli seguenti:

Per cosa e perché si usano gli iteratori Python?

Il campo d’ap­pli­ca­zio­ne prin­ci­pa­le degli iteratori è na­tu­ral­men­te l’ite­ra­zio­ne stessa. Il grande vantaggio degli iteratori Python è che fun­zio­na­no secondo il principio della “va­lu­ta­zio­ne pigra”. In altre parole, ciascun elemento di un iteratore Python può essere elaborato sin­go­lar­men­te, senza dover caricare in memoria l’intera struttura di dati. Questo com­por­ta­men­to risulta par­ti­co­lar­men­te ef­fi­cien­te in presenza di grandi quantità di dati, perché così in ogni momento si deve caricare un solo elemento.

Come creare iteratori Python

Creare un proprio iteratore Python non è difficile. Basta ag­giun­ge­re a un oggetto Python le funzioni iter() e next(). Potete così creare molto fa­cil­men­te un iteratore che re­sti­tui­sce tutti i numeri pari. L’esempio di codice mostra l’esatto fun­zio­na­men­to:

class numeripari:
	def __iter__(self):
		self.x = 0
		return self
	def __next__(self):
		a = self.x
		self.x += 2
		return a
testobject = numeripari()
testiterator = iter(testobject)
print(next(testiterator))
print(next(testiterator))
print(next(testiterator))
print(next(testiterator))
Python

Per rea­liz­za­re un iteratore Python, prima si crea una classe che qui reca il nome “nu­me­ri­pa­ri”. All’interno della classe si im­ple­men­ta­no le due funzioni iter() e next() con il com­por­ta­men­to de­si­de­ra­to.

Nel nostro caso, la funzione iter() re­sti­tui­sce solo un ri­fe­ri­men­to all’iteratore, che deve ospitare la sequenza numerica completa a partire da 0. La logica dell’ite­ra­zio­ne, cioè che viene re­sti­tui­to solo un numero su due (quindi solo i numeri pari), si trova all’interno della funzione next().

Una volta definita la classe, si crea un oggetto della classe da inserire nella variabile chiamata “te­sto­b­ject”. L’oggetto diventa un iteratore Python chiamando la funzione iter(), come abbiamo già mostrato nell’esempio di codice pre­ce­den­te. Seguono quattro chiamate di next(), i cui risultati sono re­sti­tui­ti sullo schermo. L’output della sezione di codice sopra si presenta come segue:

0
2
4
6

Li­mi­ta­zio­ne degli iteratori Python

Senza una li­mi­ta­zio­ne, l’iteratore che itera sui numeri pari girerebbe all’infinito, proprio come la quantità di numeri pari. È possibile impedirlo con un’istru­zio­ne “Sto­pI­te­ra­tion” abbinata a un’istru­zio­ne if-else in Python. Se volete che il vostro iteratore Python re­sti­tui­sca ad esempio tutti i numeri pari fino a 100 compreso, dovete mo­di­fi­ca­re l’esempio di codice sopra come segue:

class numeripari:
	def __iter__(self):
		self.x = 0
		return self
	def __next__(self):
		if self.x <= 100:
			a = self.x
			self.x += 2
			return a	
		else:
			StopIteration
testobject = numeripari()
testiterator = iter(testobject)
print(next(testiterator))
print(next(testiterator))
print(next(testiterator))
print(next(testiterator))
Python

Nel codice, a parte l’im­ple­men­ta­zio­ne della funzione next(), non è cambiato nulla. Qui è stata integrata un’ulteriore istru­zio­ne if-else che verifica se il numero corrente è inferiore o pari a 100. Solo a questa con­di­zio­ne si continua a iterare sulla quantità di numeri pari. Se il numero supera 100, chiamando Sto­pI­te­ra­tion viene generato un errore.

Vai al menu prin­ci­pa­le