Ce face yield (generatoare)
O funcție care conține yield nu rulează imediat când o apelezi: returnează un generator. La fiecare pas (într-un for sau cu next()), funcția rulează până la următorul yield, dă valoarea și se oprește acolo, păstrându-și starea.
Generatoarele produc valorile pe rând, fără să țină toată lista în memorie. Sunt potrivite pentru fișiere mari, șiruri foarte lungi sau chiar infinite. yield from colectie produce, pe rând, toate elementele altei colecții sau ale altui generator.
Exemple
Exemplul 1: Un generator simplu
def numaratoare(n):
while n > 0:
yield n
n -= 1
for x in numaratoare(3):
print(x)
print(list(numaratoare(5)))
Rezultat
3
2
1
[5, 4, 3, 2, 1]
Exemplul 2: Valori calculate la cerere
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
gen = fibonacci()
print([next(gen) for _ in range(10)])
Rezultat
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Exemplul 3: yield from
def toate_produsele(categorii):
for produse in categorii.values():
yield from produse
magazin = {"fructe": ["mere", "pere"], "lactate": ["lapte", "brânză"]}
print(list(toate_produsele(magazin)))
Rezultat
['mere', 'pere', 'lapte', 'brânză']
Greșeli frecvente
- Parcurgi un generator de două ori. A doua oară nu mai produce nimic; creează unul nou sau salvează valorile într-o listă.
- Folosești
return valoareîntr-un generator așteptând să fie produsă.returndoar oprește generatorul.
Comenzi înrudite
iter() și next(): iter() obține un iterator dintr-o colecție; next() ia următorul element din iterator.for: Parcurge, pe rând, fiecare element dintr-o listă, text, dicționar sau alt obiect iterabil.List comprehension: Construiește o listă nouă dintr-o altă colecție, într-un singur rând.itertools.islice(): Ia o „felie” dintr-un iterator sau generator, ca [start:stop:pas] la liste.