I generatori in Python sono un tipo di iterabile, come le liste o i tuple. Tuttavia, a differenza delle liste, non permettono l’indicizzazione con indici arbitrari, ma possono essere iterate solo una volta: generando ogni valore in modo pigro (“lazy”), ovvero solo quando è necessario.
Questo può essere molto conveniente per risparmiare memoria, specialmente quando si lavora con una grande quantità di dati.
I generatori sono costruiti usando una sintassi simile a quella delle funzioni, ma invece di ritornare i valori con un `return`, utilizzano la parola chiave `yield`.
Ecco un semplice esempio di generatore:
```
def mio_generatore():
i = 0
while True:
yield i
i += 1
```
Questo generatore continuerà all’infinito ad emettere numeri interi in ordine crescente. Puoi utilizzarlo in questo modo:
```
gen = mio_generatore()
for i in gen:
print(i)
if i > 5:
break
```
In questo esempio, il ciclo continuerà all’infinito a meno che non venga interrotto con `break`. Ogni volta che viene chiamato `next()` sul generatore, ricomincia da dove era rimasto all’ultima chiamata a `yield`, conservando tutte le variabili locali.
La parola chiave `yield` può anche essere usata come espressione, ad esempio per assegnare un valore inviato al generatore con il metodo `send()`. Infine, i generatori possono essere fermati forzatamente tramite il metodo `close()`.