Cedere Python Tutorial: Generator & Esempio di rendimento vs rendimento
Cosa è Python prodotto?
La parola chiave yield in Python funziona come un return con only
La differenza è che invece di restituire un valore, restituisce un oggetto generatore al chiamante.
Quando una funzione viene chiamata e il thread di esecuzione trova una parola chiave yield nella funzione, l'esecuzione della funzione si arresta su quella riga e restituisce un oggetto generatore al chiamante.
Sintassi
yield expression
Descrizione
Python yield restituisce un oggetto generatore. Generators sono funzioni speciali che devono essere ripetute per ottenere i valori.
La parola chiave yield converte l'espressione data in una funzione generatore che restituisce un oggetto generatore. Per ottenere i valori dell'oggetto, deve essere iterato per leggere i valori dati a yield.
Esempio: metodo di rendimento
Ecco un semplice esempio di rendimento. La funzione testyield() ha una parola chiave yield con la stringa “Benvenuti in Guru99 Python Tutorial". Quando la funzione viene chiamata, l'output viene stampato e fornisce un oggetto generatore invece del valore effettivo.
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() print(output)
Produzione:
<generator object testyield at 0x00000028265EB9A8>
L'output fornito è un oggetto generatore, che ha il valore che abbiamo assegnato a yield.
Ma non stiamo ricevendo il messaggio che dobbiamo dare per produrre risultati!
Per stampare il messaggio inviato a yield sarà necessario iterare l'oggetto generatore come mostrato nell'esempio seguente:
def testyield():
yield "Welcome to Guru99 Python Tutorials"
output = testyield()
for i in output:
print(i)
Produzione:
Welcome to Guru99 Python Tutorials
Che cosa sono Generators in Python?
Generators sono funzioni che restituiscono un oggetto generatore iterabile. I valori dall'oggetto generatore vengono recuperati uno alla volta anziché l'elenco completo insieme e quindi per ottenere i valori effettivi puoi usare un ciclo for, usando il metodo next() o list().
utilizzando Generator funzione
È possibile creare generatori utilizzando la funzione generatore e l'espressione generatore.
Una funzione generatrice è come una funzione normale: invece di avere un valore di ritorno, avrà una parola chiave yield.
Per creare una funzione generatore dovrai aggiungere una parola chiave yield. Gli esempi seguenti mostrano come creare una funzione generatore.
def generator():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
test = generator()
for i in test:
print(i)
Produzione:
H E L L O
Differenza tra la funzione normale v/s Generator funzione.
Cerchiamo di capire in che modo una funzione generatrice si differenzia da una funzione normale.
Ci sono 2 funzioni normal_test() e generator_test().
Entrambe le funzioni dovrebbero restituire la stringa "Hello World". normal_test() utilizza return e generator_test() utilizza yield.
# Normal function
def normal_test():
return "Hello World"
#Generator function
def generator_test():
yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function
Produzione:
Hello World <generator object generator_test at 0x00000012F2F5BA20>
L'output mostra che quando si chiama la funzione normale normal_test() restituisce la stringa Hello World. Per una funzione generatore con parola chiave yield restituisce e non la corda.
Questa è la differenza principale tra una funzione generatore e una funzione normale. Ora, per ottenere il valore dall'oggetto generatore, dobbiamo usare l'oggetto all'interno del ciclo for o usare il metodo next() o usare list().
print(next(generator_test())) # will output Hello World
Un'ulteriore differenza da aggiungere alla funzione normale rispetto alla funzione del generatore è che quando si chiama una funzione normale l'esecuzione inizierà e si fermerà quando raggiungerà ritorno e il valore viene restituito al chiamante. Pertanto, quando inizia l'esecuzione, non è possibile interrompere la normale funzione nel frattempo e si fermerà solo quando si incontra la parola chiave return.
Ma nel caso della funzione generatore, una volta che l'esecuzione inizia quando ottiene il primo rendimento, interrompe l'esecuzione e restituisce l'oggetto generatore. Puoi usare l'oggetto generatore per ottenere i valori e anche mettere in pausa e riprendere in base alle tue esigenze.
Come leggere i valori dal generatore?
È possibile leggere i valori da un oggetto generatore utilizzando list(), un ciclo for e il metodo next().
Utilizzando: lista()
Una lista è un oggetto iterabile i cui elementi sono racchiusi tra parentesi. Utilizzando list() su un oggetto generatore si otterranno tutti i valori contenuti nel generatore.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(list(num))
Produzione:
[0, 2, 4, 6, 8]
Usando: for-in
Nell'esempio, c'è una funzione definita even_numbers() che ti darà tutti i numeri pari per l'n definito. La chiamata alla funzione even_numbers() restituirà un oggetto generatore, che viene utilizzato all'interno del ciclo for.
Esempio:
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
Produzione:
0 2 4 6 8
Usando next()
Il metodo next() ti fornirà l'elemento successivo nell'elenco, nell'array o nell'oggetto. Una volta che la lista è vuota, e se viene chiamato next(), restituirà un errore con il segnale stopIteration. Questo errore, da next() indica che non ci sono più elementi nell'elenco.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
Produzione:
0
2
4
6
8
Traceback (most recent call last):
File "main.py", line 11, in <module>
print(next(num))
StopIteration
GeneratorI messaggi sono utilizzabili una sola volta
Nel caso dei generatori, sono disponibili per l'uso una sola volta. Se provi a usarli di nuovo, saranno vuoti.
Per esempio:
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
print("\n")
print("Calling the generator again: ", list(num))
Produzione:
0 2 4 6 8 Calling the generator again: []
Nel caso in cui desideri che l'output venga utilizzato nuovamente, dovrai effettuare nuovamente la chiamata alla funzione.
Esempio: Generators e rendimento per la serie di Fibonacci
L'esempio seguente mostra come utilizzare i generatori e la resa in Python. L'esempio genererà la serie di Fibonacci.
def getFibonnaciSeries(num):
c1, c2 = 0, 1
count = 0
while count < num:
yield c1
c3 = c1 + c2
c1 = c2
c2 = c3
count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
print(i)
Produzione:
<generator object getFibonnaciSeries at 0x0000007F39C8BA20> 0 1 1 2 3 5 8
Esempio: chiamata alla funzione con Yield
In questo esempio vedremo come chiamare una funzione con yield.
L'esempio seguente ha una funzione chiamata test() che restituisce il quadrato del numero specificato. Esiste un'altra funzione chiamata getSquare() che utilizza test() con la parola chiave yield. L'output fornisce il valore quadrato per un determinato intervallo di numeri.
def test(n):
return n*n
def getSquare(n):
for i in range(n):
yield test(i)
sq = getSquare(10)
for i in sq:
print(i)
Produzione:
0 1 4 9 16 25 36 49 64 81
Quando utilizzare Rendimento invece di Rendimento Python
Python3 Resa La parola chiave restituisce un generatore al chiamante e l'esecuzione del codice inizia solo quando il generatore viene iterato.
A ritorno in una funzione è la fine dell'esecuzione della funzione e al chiamante viene restituito un singolo valore.
Ecco la situazione in cui dovresti usare Yield invece di Return
- Utilizza yield anziché return quando la dimensione dei dati è elevata
- Yield è la scelta migliore quando hai bisogno che l'esecuzione sia più veloce su set di dati di grandi dimensioni
- Utilizza yield quando vuoi restituire un grande insieme di valori alla funzione chiamante
- Il rendimento è un modo efficiente di produrre dati grandi o infiniti.
Rendimento vs rendimento
Ecco le differenze tra rendimento e rendimento
| dare la precedenza | Rientro |
|---|---|
| Yield restituisce un oggetto generatore al chiamante e l'esecuzione del codice inizia solo quando il generatore viene iterato. | Un ritorno in una funzione è la fine dell'esecuzione della funzione e al chiamante viene restituito un singolo valore. |
| Quando la funzione viene chiamata e incontra la parola chiave yield, l'esecuzione della funzione si arresta. Restituisce l'oggetto generatore al chiamante. L'esecuzione della funzione inizierà solo quando l'oggetto generatore viene eseguito. | Quando viene chiamata la funzione, l'esecuzione inizia e il valore viene restituito al chiamante se è presente la parola chiave return. Il ritorno all'interno della funzione segna la fine dell'esecuzione della funzione. |
| espressione di resa | espressione di ritorno |
| Non viene utilizzata memoria quando viene utilizzata la parola chiave yield. | La memoria viene allocata per il valore restituito. |
| Molto utile se si ha a che fare con dati di grandi dimensioni in quanto la memoria non viene utilizzata. | Conveniente per dimensioni dei dati molto ridotte. |
| Le prestazioni sono migliori se la parola chiave yield viene utilizzata per dati di grandi dimensioni. | Se la dimensione dei dati è enorme, viene utilizzata molta memoria, il che ostacolerà le prestazioni. |
| Il tempo di esecuzione è più veloce in caso di resa per dati di grandi dimensioni. | Il tempo di esecuzione utilizzato è maggiore in quanto viene eseguita un'elaborazione aggiuntiva nel caso in cui la dimensione dei dati sia enorme, funzionerà correttamente per dimensioni di dati ridotte. |
Sintesi
- La parola chiave yield in Python funziona come return, con l'unica differenza che invece di restituire un valore, restituisce una funzione generatrice al chiamante.
- Un generatore è un tipo speciale di iteratore che, una volta utilizzato, non sarà più disponibile. I valori non vengono salvati in memoria e sono disponibili solo quando vengono chiamati.
- I valori del generatore possono essere letti utilizzando i metodi for-in, list() e next().
- La differenza principale tra yield e return è che yield restituisce una funzione generatrice al chiamante, mentre return fornisce un singolo valore al chiamante.
- Yield non memorizza nessuno dei valori in memoria e il vantaggio è che è utile quando la dimensione dei dati è grande, poiché nessuno dei valori viene archiviato in memoria.
- Il rendimento è migliore se viene utilizzata la parola chiave yield rispetto a return per dati di grandi dimensioni.
