Maîtriser yield en Python : générateur vs return – Guide pratique
Maîtriser yield en Python : générateur vs return – Guide pratique
Qu'est-ce que yield en Python ?
Le mot-clé yield se comporte comme return, mais au lieu de renvoyer une valeur immédiatement, il renvoie un objet générateur qui peut être itéré. Quand une fonction contenant yield est invoquée, l'exécution se met en pause au premier yield et rend le contrôle à l'appelant avec un générateur. Les appels suivants à next() ou une boucle for reprennent l'exécution depuis ce point, produisant la valeur suivante.
Points clés à retenir
- Yield crée un générateur, permettant l'évaluation paresseuse.
- Les générateurs sont efficaces en mémoire pour les séquences grandes ou infinies.
- La lecture depuis un générateur se fait avec
for-in,list()ounext(). - Une fois épuisé, un générateur ne peut pas être réutilisé ; rappelez la fonction.
Syntaxe
yield expression
Exemple pratique : un yield simple
def test_yield():
yield "Bienvenue sur les tutoriels Python Guru99"
resultat = test_yield()
print(resultat)
Sortie :
<generator object test_yield at 0x00000028265EB9A8>
L'objet générateur contient la valeur produite. Pour y accéder, itérez :
for valeur in resultat:
print(valeur)
Sortie :
Bienvenue sur les tutoriels Python Guru99
Générateurs expliqués
Une fonction générateur est une fonction spéciale qui renvoie un objet générateur itérable. Contrairement aux fonctions régulières qui renvoient une seule valeur, un générateur produit une séquence de valeurs paresseusement, générant chacune seulement quand demandée.
Créer une fonction générateur
def generateur_exemple():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
for lettre in generateur_exemple():
print(lettre)
Sortie :
H E L L O
Fonction normale vs fonction générateur
Considérez la paire de fonctions suivante :
# Fonction normale
def test_normal():
return "Hello World"
# Fonction générateur
def test_generateur():
yield "Hello World"
print(test_normal()) # → Hello World
print(test_generateur()) # → <generator object test_generateur>
Les fonctions normales se terminent au return ; les générateurs font pause au yield, rendant le contrôle à l'appelant avec un objet générateur.
Consommer un générateur
Vous pouvez tirer des valeurs d'un générateur en utilisant :
- Boucles
for-in list()pour matérialiser toutes les valeursnext()pour un pas à pas manuel
Exemple : Nombres pairs
def nombres_pairs(n):
for x in range(n):
if x % 2 == 0:
yield x
print(list(nombres_pairs(10))) # → [0, 2, 4, 6, 8]
Utiliser for-in
for num in nombres_pairs(10):
print(num)
Sortie :
0 2 4 6 8
Utiliser next()
gen = nombres_pairs(10)
for _ in range(6):
try:
print(next(gen))
except StopIteration:
print("Fin du générateur")
Sortie :
0 2 4 6 8 Fin du générateur
Les générateurs sont à usage unique
Une fois qu'un générateur a été entièrement itéré, il est épuisé. Ré-itérer ne produit rien à moins de rappeler la fonction générateur.
gen = nombres_pairs(10)
for num in gen:
print(num)
print(list(gen)) # → []
Yield en action : Série de Fibonacci
def serie_fibonacci(limite):
a, b = 0, 1
compteur = 0
while compteur < limite:
yield a
a, b = b, a + b
compteur += 1
fib = serie_fibonacci(7)
for num in fib:
print(num)
Sortie :
0 1 1 2 3 5 8
Appeler une fonction qui yield
Ci-dessous, nous mettons au carré des nombres en utilisant une fonction auxiliaire et un générateur qui produit chaque résultat.
def carre(n):
return n * n
def carre_range(n):
for i in range(n):
yield carre(i)
for valeur in carre_range(10):
print(valeur)
Sortie :
0 1 4 9 16 25 36 49 64 81
Quand utiliser yield plutôt que return
- Traitement de données volumineuses ou en flux où charger tous les éléments à la fois est impraticable.
- Génération de séquences potentiellement infinies (ex. : lecteurs de fichiers paresseux).
- Amélioration de l'empreinte mémoire et du temps de démarrage pour les gros jeux de données.
- Quand vous avez besoin de mettre en pause et reprendre le calcul, pas seulement renvoyer une valeur finale.
Yield vs Return – Référence rapide
| Yield | Return |
|---|---|
| Renvoie un générateur ; l'exécution reprend à l'itération. | Termine la fonction ; renvoie une valeur unique immédiatement. |
Fait pause à chaque yield, économisant la mémoire. | Alloue de la mémoire pour la valeur retournée. |
| Idéal pour les séquences grandes ou infinies. | Adapté aux résultats petits et discrets. |
| Temps d'exécution plus rapide pour gros jeux de données. | Peut engendrer une surcharge avec d'énormes données. |
Points clés à retenir
- Yield produit un objet générateur, pas une valeur.
- Les générateurs livrent les valeurs paresseusement, gardant l'usage mémoire minimal.
- Lisez les valeurs via
for-in,list()ounext(). - Une fois épuisés, les générateurs doivent être recréés pour être réutilisés.
- Yield surpasse return pour les données grandes ou en flux.
Python
- Fonctions lambda en Python : Guide pratique des fonctions anonymes
- Générateurs Python : itération efficace et cas d'utilisation avancés
- Les fermetures Python expliquées : comment les fonctions imbriquées capturent les variables
- Maîtriser les décorateurs Python : améliorer les fonctions avec des techniques expertes
- Maîtriser la méthode strip() de Python : Guide complet et exemples pratiques
- Python len() : Guide pratique pour mesurer la longueur des objets
- Maîtriser les fonctions lambda Python : exemples pratiques et bonnes pratiques
- Fonction Python round() expliquée avec exemples pratiques
- Maîtriser la fonction Python map() : syntaxe, exemples et bonnes pratiques