In Python un generatore  è una funzione che ritorna un iteratore, senza dover definire una classe e i metodi visti nell'articolo precedente.

Perchè vengono usati i generatori in Python

  • Sono efficienti se comparati ad una funzione "normale" che deve ritornare una sequenza di elementi(es. una lista) perchè i generatori producono un elemento alla volta, mentre quest'ultime creano l'intera sequenza appena vengono richiamate, il che può essere un problema se si tratta di sequenze con molti elementi;
  • Possono essere utilizzati per rappresentare una quantità potenzialmente infinita di valori in quanto produce solamente un elemento per volta;
  • Sono Facili da implementare rispetto alla creazione "manuale" degli iteratori;

Creare dei generatori "al volo"

>>> generatore = (x for x in [1, 2, 3, 4, 6, 7])

>>> print(next(generatore))
1
>>> print(next(generatore))
2
>>> print(next(generatore))
3

Nota: il generatore ritorna un oggetto iteratore, quindi andrà trattato come tale. Se non sai cos'è un iteratore vai a questo post.

Come hai potuto vedere, creare un generatore in questo modo è piuttosto semplice, molto simile alle list comprehensions. Tuttavia, come accennato inizialmente, i generatori sono delle funzioni, perciò per scrivere dei generatori un pò più complessi dovremo andare a definire una funzione generatore.

Le Funzioni generatore

Le funzioni generatore non sono altro che funzioni che ritornano un oggetto iteratore e utilizzano il comando yield al posto di return per ritornare il prossimo elemento:

def funzione_generatore():
    yield "Primo elemento!"
    yield "Secondo elemento!"
    yield "Terzo elemento!"

generatore = funzione_generatore()
print(next(generatore))
#output: Primo elemento!

print(next(generatore))
#output: Secondo elemento!

print(next(generatore))
#output: Terzo elemento!

print(next(generatore))
# - non ci sono più elementi - #output -solleva l'eccezione StopIteration-

Ogni volta che viene richiamato uno yield, la funzione si mette in pausa e le variabili locali rimangono salvate in memoria:

def funzione_generatore():
contatore = 1 yield contatore

contatore = contatore * 3 yield contatore

contatore = contatore * 3
yield contatore generatore = funzione_generatore() print(next(generatore)) #output: 1 print(next(generatore)) #output: 3 print(next(generatore)) #output: 9 print(next(generatore))
# - non ci sono più elementi - #output -solleva l'eccezione StopIteration-

For loop con i generatori

Come utilizzare un for loop in una funzione generatore:

def funzione_generatore(sequenza):
for elemento in sequenza:
yield elemento * 2 for x in funzione_generatore([3, 2, 5, 7):
print(x)

#output:
#6
#4
#10
#17

Conclusione

Bene! Siamo giunti al termine del post... ora sai come funziona un generatore e come crearne uno.

Spero di esserti stato utile e se lo sono stato ti invito a condividere l'articolo sui social e a seguirmi su twitter e instagram, alla prossima!


Condividi sui Social