yield (generatoare) în Python

Iteratoare și generatoare Python 3.0+ (yield from: 3.3+)

Transformă o funcție într-un generator, care produce valorile una câte una, la cerere.

Sintaxă
def generator():
    yield valoare
    yield from alt_iterabil

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ă. return doar 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.