Exercice 46 / 100

Générateurs

ConsigneCréez un générateur de nombres pairs infinis

📖 Cours

Un générateur est une fonction qui produit des valeurs une à la fois, à la demande. Au lieu de return, on utilise yield. Avantage majeur : pas besoin de tout charger en mémoire.

yield vs return

return → termine la fonction et renvoie une valeur (la fonction "finit")yield → renvoie une valeur mais MET LA FONCTION EN PAUSE. À l'appel suivant, elle reprend là où elle s'était arrêtée.

Une fonction qui contient yield est automatiquement un générateur.

Un générateur avance à la demande : chaque next() le réveille, yield rend une valeur puis remet la fonction en pause avec son état, et cela tourne jusqu'à ce que la fonction se termine, où next() lève StopIteration (le générateur infini de la leçon, lui, ne se termine jamais)
Un générateur avance à la demande : chaque next() le réveille, yield rend une valeur puis remet la fonction en pause avec son état, et cela tourne jusqu'à ce que la fonction se termine, où next() lève StopIteration (le générateur infini de la leçon, lui, ne se termine jamais)

Exemple : nombres pairs infinis

def pairs_infinis(): n = 0 while True: yield n n += 2
gen = pairs_infinis() # ne calcule rien, prépare le générateurnext(gen) # 0next(gen) # 2next(gen) # 4

Ou avec une boucle

for _ in range(5): print(next(gen))

Si tu fais for v in pairs_infinis(): print(v) — boucle infinie ! Combine avec un break ou avec itertools.islice.

Pourquoi un générateur ?

- Lazy evaluation : on ne calcule la valeur que quand on en a besoin.- Mémoire : un générateur stocke seulement son état, pas TOUTES les valeurs.- Possibilité de séquences infinies (impossibles en liste).

Exemple : lire un gros fichier ligne par ligne sans tout charger :

def lire_lignes(chemin): with open(chemin) as f: for ligne in f: yield ligne.strip()

Generator expression

Forme courte avec des parenthèses (au lieu de crochets pour une list comprehension) :

carres = (x ** 2 for x in range(10)) # générateursum(x ** 2 for x in range(10)) # parenthèses optionnelles ici

Les parenthèses ne sont optionnelles que si la generator expression est le seul argument de l'appel. Dès qu'il y en a un second, elles redeviennent obligatoires, sinon Python refuse de compiler :

sum(x ** 2 for x in range(10), 0) # SyntaxErrorsum((x ** 2 for x in range(10)), 0) # correct

Règle : si tu vas itérer une seule fois et que la collection est grande, préfère un générateur à une liste.

Envie d'aller plus loin ? Découvrez nos formations certifiées Bac+2 à Bac+5 →