Introduzione ai generatori Python

I generatori semplificano la creazione di iterazioni in Python e, in cambio, scrivono meno codice. Questo tutorial ti introdurrà ai generatori Python, ai loro benefici e al loro funzionamento.

Nozioni di base

Un generatore è una funzione che restituisce un oggetto generatore su cui è possibile chiamare il Il prossimo() metodo, in modo che per ogni chiamata restituisca un valore o il valore successivo. Una normale funzione Python usa il ritorno parola chiave per restituire valori, ma i generatori usano la parola chiave dare la precedenza per restituire valori. Ciò significa che qualsiasi funzione Python contenente a dare la precedenza la dichiarazione è una funzione generatrice.

Il dare la precedenza la dichiarazione di solito interrompe la funzione e salva lo stato locale in modo che possa essere ripreso esattamente da dove era stato interrotto. Le funzioni del generatore possono avere uno o più dare la precedenza dichiarazioni.

Un generatore è anche un iteratore, ma cos'è un iteratore? Prima di immergerci nei dettagli dei generatori, penso che sia importante sapere quali sono gli iteratori perché sono parte integrante di questa discussione.

Iterator di Python

Un iteratore Python è semplicemente una classe che definisce un __iter __ () metodo. La maggior parte degli oggetti Python sono iterabili, il che significa che puoi scorrere su ogni singolo elemento degli oggetti. Esempi di iterabili in Python includono stringhe, liste, tuple, dizionari e intervalli.

Consideriamo l'esempio seguente, in cui stiamo eseguendo il ciclo su un elenco di colori:

colors = ["red", "blue", "yellow"] def my_funct (): per colore nei colori: colore di stampa

Dietro le quinte, il per la dichiarazione chiamerà iter () sull'oggetto lista. La funzione restituirà quindi un oggetto iteratore che definisce il metodo __Il prossimo__(), che poi accederà a ciascun colore, uno alla volta. Quando non ci sono più colori rimasti, __Il prossimo__ alzerà un StopIteration eccezione, che a sua volta informerà il per ciclo da terminare.

Iterare su un dizionario

d = 'x': 10, 'y': 20, 'z': 30 per k, v in d.items (): print k, v #result # y 20 # x 10 # z 30 

Iterating Over Rows in un file CSV

importare csv con open ('file.csv', newline = ") come File: reader = csv.reader (File) per riga nel reader: yield row

Iterating Over a String

my_string = 'Generatori' per la stringa in my_string: print (stringa) #risult # G # e # n # e # r # a # t # o # r # s

Vantaggi dell'utilizzo di generatori

Discutiamo alcuni dei vantaggi dell'utilizzo di generatori rispetto agli iteratori:

Facile da implementare

Costruire un iteratore in Python richiede di implementare una classe con __iter __ () e __Il prossimo__() metodi oltre a prendersi cura di eventuali errori che potrebbero causare a StopIteration errore.

classe Reverse: "" "Iterator per il looping su una sequenza all'indietro." "" def __init __ (self, data): self.data = data self.index = len (data) def __iter __ (self): return self def __next __ (self ): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data [self.index]

Come puoi vedere sopra, l'implementazione è molto lunga. Tutto questo carico viene gestito automaticamente dai generatori.

Meno consumo di memoria

I generatori aiutano a minimizzare il consumo di memoria, soprattutto quando si gestiscono insiemi di dati di grandi dimensioni, perché un generatore restituirà solo un elemento alla volta.

Migliori prestazioni e ottimizzazione

I generatori sono pigri in natura. Ciò significa che generano solo valori quando richiesto. A differenza di un normale iteratore, in cui tutti i valori vengono generati indipendentemente dal fatto che vengano utilizzati o meno, i generatori generano solo i valori necessari. Questo, a sua volta, porterà il tuo programma ad esibirsi più rapidamente.

Come creare un generatore in Python

Creare un generatore è molto semplice. Tutto ciò che devi fare è scrivere una funzione normale, ma con a dare la precedenza affermazione invece di a ritorno dichiarazione, come mostrato di seguito.

def gen_function (): resa "python"

Mentre a ritorno la dichiarazione termina completamente una funzione, dare la precedenza basta mettere in pausa la funzione fino a quando non viene richiamata da Il prossimo() metodo.

Ad esempio, il programma seguente utilizza entrambi dare la precedenza e Il prossimo() dichiarazioni.

def myGenerator (l): total = 1 per n in l: yield total total + = n newGenerator = myGenerator ([10,3]) print (next (newGenerator)) print (next (newGenerator)) 

Come funzionano i generatori Python

Vediamo come funzionano i generatori. Considera l'esempio qui sotto.

# generator_example.py def myGenerator (l): total = 0 per n in l: total + = n yield total newGenerator = myGenerator ([10,20,30]) print (next (newGenerator)) print (next (newGenerator)) stampa (accanto (newGenerator)) 

Nella funzione sopra, definiamo un generatore chiamato myGenerator, che prende una lista l come argomento. Quindi definiamo una variabile totale e assegnagli un valore pari a zero. Inoltre, passiamo in rassegna ogni elemento dell'elenco e successivamente lo aggiungiamo alla variabile totale.

Quindi istanziamo newGenerator e chiama il Il prossimo() metodo su di esso. Ciò eseguirà il codice finché non produce il primo valore di totale, che sarà 0 in questo caso. La funzione mantiene quindi il valore della variabile totale fino alla successiva chiamata della funzione. A differenza di un normale ritorno dichiarazione, che restituirà tutti i valori in una volta, il generatore riprenderà da dove era stato interrotto.

Di seguito sono riportati i restanti valori successivi.

# generator_example.py def myGenerator (l): total = 0 per n in l: yield total total + = n newGenerator = myGenerator ([10,20,30]) print (next (newGenerator)) print (next (newGenerator)) print (next (newGenerator)) # result # 0 # 10 # 30 

Se provi a chiamare la funzione dopo aver completato il ciclo, otterrai a StopIteration errore.

UN StopIteration è allevato dal Il prossimo() metodo per segnalare che non ci sono ulteriori elementi prodotti dall'iteratore.

0 10 30 Traceback (ultima chiamata ultima): File "python", riga 15, in  Funzione StopIterationNormal 

Esempio 2

In questo esempio, mostriamo come utilizzare più dichiarazioni di rendimento in una funzione.

# colors.py def colors (): resa "red" resa "blue" resa "green" next_color = colors () print (next (next_color)) print (next (next_color)) print (next (next_color)) # result # rosso # blu # verde

Mentre una funzione normale restituisce tutti i valori quando la funzione è chiamata, un generatore attende fino a Il prossimo() il metodo è chiamato di nuovo. Una volta Il prossimo() viene chiamato, la funzione colori riprende da dove si era fermato.

Conclusione

I generatori sono più efficienti in termini di memoria, soprattutto quando si lavora con elenchi molto grandi o oggetti grandi. Questo perché è possibile utilizzare i rendimenti per lavorare su bit più piccoli piuttosto che avere tutti i dati in memoria tutti in una volta.

Inoltre, non dimenticare di vedere quello che abbiamo a disposizione per la vendita e per studiare su Envato Market, e non esitare a fare domande e fornire il tuo prezioso feedback usando il feed qui sotto.

Inoltre, se ti senti bloccato, c'è un corso molto buono sui generatori Python nella sezione del corso.