Aller au contenu
Fonctions

Générateurs (yield)

Un générateur produit ses valeurs une à une avec yield, à la demande, au lieu de tout construire en mémoire. Il convient aux gros fichiers, aux flux de logs et aux suites lues une seule fois.

  • yield
  • générateur
  • itérateur
  • next
  • mémoire
  • flux
  • itertools

Syntaxe

Modèle
def generateur(...):    for ...:        yield valeurg = generateur(...)next(g)          for x in g: ...(expr for x in iterable)       # expression génératrice

Exemple

Exemple concret
logs = """2026-11-02 10:01 INFO connexion ana2026-11-02 10:03 ERROR timeout api2026-11-02 10:04 INFO export bob2026-11-02 10:07 ERROR disque plein"""def erreurs(lignes):    for ligne in lignes:        if " ERROR " in ligne:            yield ligne.split(" ERROR ")[1]g = erreurs(logs.splitlines())print(next(g))      # → timeout apiprint(list(g))      # → ['disque plein']print(list(g))      # → []    (le générateur est épuisé)

À retenir

  1. Une fonction qui contient yield ne s'exécute pas à l'appel : elle renvoie un générateur, et le code avance jusqu'au yield suivant à chaque next() ou tour de boucle.
  2. Piège : un générateur s'épuise. Une fois parcouru, un second list(g) renvoie une liste vide ; recréez-le, ou stockez le résultat dans une liste si vous devez le relire.
  3. Les générateurs s'enchaînent en pipeline (lire, filtrer, transformer) sans jamais charger tout le fichier, d'autant qu'un fichier ouvert se parcourt déjà ligne par ligne.
  4. Piège : len(g) et g[0] ne fonctionnent pas sur un générateur. Convertissez avec list(g) si le résultat tient en mémoire, ou utilisez itertools.islice(g, 5) pour les premiers éléments.
  5. yield from autre_generateur délègue à un autre générateur ; itertools (islice, chain, groupby) fournit les briques courantes.

Voir aussi