close
Passer au contenu principal

Tutoriel sur les itérateurs et générateurs Python

Découvrez la différence entre les itérateurs et les générateurs Python et apprenez lesquels privilégier selon les situations.
Actualisé 25 mai 2026  · 10 min lire

Les itérateurs sont des objets sur lesquels on peut itérer. Il s’agit d’une fonctionnalité commune du langage Python, très utilisée dans les boucles et les compréhensions de listes. Tout objet capable de produire un itérateur est appelé un itérable. 

Créer un itérateur demande un certain travail. Par exemple, l’implémentation de chaque objet itérateur doit définir les méthodes __iter__() et __next__() . En plus de ces prérequis, l’implémentation doit suivre l’état interne de l’objet et lever une exception StopIteration lorsqu’il n’y a plus de valeurs à retourner. Ces règles constituent le protocole des itérateurs

Implémenter son propre itérateur est un processus fastidieux, et ce n’est pas toujours nécessaire. Une alternative plus simple consiste à utiliser un générateur. Les générateurs sont un type particulier de fonction qui utilisent le mot-clé yield pour retourner un itérateur pouvant être parcouru, une valeur à la fois. 

Savoir quand implémenter un itérateur et quand utiliser un générateur renforcera vos compétences de développeur Python. Dans la suite de ce tutoriel, nous mettrons en avant les distinctions entre ces deux objets afin de vous aider à choisir la meilleure approche selon les cas d’usage. 

Glossaire

Terme

Définition

Itérable 

Un objet Python qui peut être parcouru dans une boucle. Exemples : listes, ensembles, tuples, dictionnaires, chaînes de caractères, etc. 

Itérateur

Un itérateur est un objet sur lequel on peut itérer. Il contient donc un nombre dénombrable de valeurs. 

Générateur

Un type particulier de fonction qui ne renvoie pas une unique valeur : elle renvoie un objet itérateur produisant une séquence de valeurs.

Évaluation paresseuse 

Stratégie d’évaluation selon laquelle certains objets ne sont produits que lorsqu’ils sont requis. Dans certains cercles de développeurs, on parle aussi de « call-by-need ».

Protocole des itérateurs 

Un ensemble de règles à respecter pour définir un itérateur en Python. 

next()

Fonction native qui permet de retourner l’élément suivant d’un itérateur. 

iter()

Fonction native qui convertit un itérable en itérateur. 

yield()

Mot-clé Python similaire à return, sauf que yield renvoie un objet générateur au lieu d’une valeur. 

Itérateurs et itérables en Python

Les itérables sont des objets capables de retourner leurs éléments un par un : on peut donc les parcourir. Les structures de données Python intégrées les plus courantes, comme les listes, tuples et ensembles, sont des itérables. D’autres structures comme les chaînes et les dictionnaires le sont aussi : une chaîne peut être parcourue caractère par caractère et on peut itérer sur les clés d’un dictionnaire. En règle générale, tout objet que l’on peut parcourir avec une boucle for est un itérable. 

Explorer les itérables Python avec des exemples

Au vu des définitions, on peut conclure que tous les itérateurs sont aussi des itérables. En revanche, tout itérable n’est pas forcément un itérateur. Un itérable ne produit un itérateur que lorsqu’on l’itère.

Pour le démontrer, nous allons instancier une liste (un itérable) et produire un itérateur en appelant la fonction native iter() sur cette liste. 

list_instance = [1, 2, 3, 4]
print(iter(list_instance))

"""
<list_iterator object at 0x7fd946309e90>
"""

Bien que la liste en elle-même ne soit pas un itérateur, l’appel à la fonction iter() la convertit en itérateur et renvoie l’objet itérateur.

Pour montrer que tous les itérables ne sont pas des itérateurs, nous allons instancier la même liste et tenter d’appeler la fonction next(), qui sert à retourner l’élément suivant d’un itérateur.  

list_instance = [1, 2, 3, 4]
print(next(list_instance))
"""
--------------------------------------------------------------------
TypeError                         Traceback (most recent call last)
<ipython-input-2-0cb076ed2d65> in <module>()
    3 print(iter(list_instance))
    4
----> 5 print(next(list_instance))
TypeError: 'list' object is not an iterator
"""

Dans le code ci-dessus, tenter d’appeler next() sur la liste déclenche une TypeError – en savoir plus sur la gestion des exceptions et des erreurs en Python. Ce comportement s’explique simplement par le fait qu’une liste est un itérable, pas un itérateur. 

Explorer les itérateurs Python avec des exemples

Ainsi, si l’objectif est d’itérer sur une liste, il faut d’abord produire un objet itérateur. C’est seulement ensuite que l’on peut avancer dans les valeurs de la liste.

# instancier une liste
list_instance = [1, 2, 3, 4]

# convertir la liste en itérateur
iterator = iter(list_instance)

# retourner les éléments un par un
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
"""
1
2
3
4
"""

Python crée automatiquement un objet itérateur lorsque vous parcourez un itérable en boucle. 

# instancier une liste
list_instance = [1, 2, 3, 4]

# parcourir la liste
for item in list_instance:
  print(item)
"""
1
2
3
4
"""

Quand l’exception StopIteration est levée, la boucle se termine.

Les valeurs d’un itérateur ne peuvent être lues que de gauche à droite. Python ne propose pas de fonction previous() permettant de revenir en arrière dans un itérateur. 

La nature paresseuse des itérateurs

Il est possible de définir plusieurs itérateurs à partir du même itérable. Chaque itérateur maintient son propre état d’avancement. Ainsi, en définissant plusieurs instances d’itérateurs d’un même itérable, on peut atteindre la fin avec l’une pendant que l’autre reste au début.

list_instance = [1, 2, 3, 4]
iterator_a = iter(list_instance)
iterator_b = iter(list_instance)
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"A: {next(iterator_a)}")
print(f"B: {next(iterator_b)}")
"""
A: 1
A: 2
A: 3
A: 4
B: 1
"""

Remarquez que iterator_b affiche le premier élément de la série.

On peut donc dire que les itérateurs ont une nature paresseuse : à la création d’un itérateur, les éléments ne sont produits que lorsqu’ils sont demandés. Autrement dit, les éléments de notre liste ne seraient retournés que si nous les demandons explicitement avec next(iter(list_instance))

Cependant, on peut extraire toutes les valeurs d’un itérateur en une fois en appelant une structure de données itérable standard (p. ex. list(), set(), tuple()) sur l’objet itérateur pour le forcer à générer tous ses éléments d’un coup.

# instancier un itérable
list_instance = [1, 2, 3, 4]

# produire un itérateur à partir de l’itérable
iterator = iter(list_instance)
print(list(iterator))
"""
[1, 2, 3, 4]
"""

Ce n’est pas recommandé pour de grands itérateurs, car cela force la génération et la conservation en mémoire de chaque élément, ce qui va à l’encontre de l’évaluation paresseuse.

Quand un jeu de données est trop volumineux pour tenir confortablement en mémoire, ou lorsque vous souhaitez une itération paresseuse sans écrire une classe d’itérateur complète, un générateur est généralement mieux adapté.

Générateurs Python

L’alternative la plus simple à l’implémentation d’un itérateur est d’utiliser un générateur. Bien que les générateurs ressemblent à des fonctions Python classiques, ils sont différents. Pour commencer, un générateur ne renvoie pas des éléments de façon traditionnelle : il utilise le mot-clé yield pour produire des éléments à la volée. On peut donc dire qu’un générateur est un type particulier de fonction qui s’appuie sur l’évaluation paresseuse.

Les générateurs ne stockent pas leur contenu en mémoire comme on pourrait s’y attendre d’un itérable classique. Par exemple, si l’objectif est de trouver tous les diviseurs d’un entier positif, on écrirait habituellement une fonction traditionnelle (découvrez-en plus sur les fonctions Python dans ce tutoriel) comme suit :  

def factors(n):
  factor_list = []
  for val in range(1, n+1):
      if n % val == 0:
          factor_list.append(val)
  return factor_list

print(factors(20))
"""
[1, 2, 4, 5, 10, 20]
"""

Le code ci-dessus renvoie la liste complète des diviseurs. Voyez maintenant la différence lorsque l’on utilise un générateur à la place d’une fonction Python traditionnelle :

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
print(factors(20))

"""
<generator object factors at 0x7fd938271350>
"""

Puisque nous avons utilisé le mot-clé yield au lieu de return, l’exécution de la fonction ne se termine pas immédiatement. En essence, nous avons demandé à Python de créer un objet générateur plutôt qu’une fonction traditionnelle, ce qui permet de suivre l’état du générateur. 

Il devient alors possible d’appeler la fonction next() sur cet itérateur paresseux pour révéler les éléments de la série un par un. 

def factors(n):
  for val in range(1, n+1):
      if n % val == 0:
          yield val
         
factors_of_20 = factors(20)
print(next(factors_of_20))

"""
1
"""

Une autre manière de créer un générateur est d’utiliser une compréhension de générateur. La syntaxe est similaire à celle d’une compréhension de liste, mais avec des parenthèses au lieu des crochets.

factor_gen = (val for val in range(1, 21) if 20 % val == 0)
print(list(factor_gen))
"""
[1, 2, 4, 5, 10, 20]
"""

Comprendre le mot-clé yield en Python

Le mot-clé yield contrôle le flux d’une fonction génératrice. Au lieu de quitter la fonction comme avec return, yield renvoie une valeur mais mémorise l’état de ses variables locales.

Le générateur retourné par l’appel à yield peut être affecté à une variable puis parcouru avec la fonction next() – cela exécutera la fonction jusqu’au premier yield rencontré. Une fois le yield atteint, l’exécution de la fonction est suspendue. À ce moment, l’état de la fonction est sauvegardé. Il est donc possible de reprendre l’exécution quand on le souhaite. 

La fonction reprendra à partir de l’appel à yield. Par exemple : 

def yield_multiple_statements():
  yield "This is the first statement"
  yield "This is the second statement"  
  yield "This is the third statement"
  yield "This is the last statement. Don't call next again!"
example = yield_multiple_statements()
print(next(example))
print(next(example))
print(next(example))
print(next(example))
print(next(example))
"""
This is the first statement
This is the second statement
This is the third statement
This is the last statement. Don't call next again or else!
--------------------------------------------------------------------
StopIteration                  Traceback (most recent call last)
<ipython-input-25-4aaf9c871f91> in <module>()
    11 print(next(example))
    12 print(next(example))
---> 13 print(next(example))
StopIteration:
"""

Dans le code ci-dessus, notre générateur comporte quatre appels à yield, mais nous appelons next cinq fois, ce qui lève une exception StopIteration. Ce comportement survient parce que notre générateur n’est pas une série infinie : l’appeler plus de fois qu’il n’y a d’éléments épuise le générateur.

En résumé 

Pour récapituler, les itérateurs sont des objets sur lesquels on peut itérer, et les générateurs sont des fonctions particulières qui s’appuient sur l’évaluation paresseuse. Implémenter votre propre itérateur implique de définir les méthodes __iter__() et __next__(), tandis qu’un générateur s’implémente en utilisant le mot-clé yield dans une fonction ou une compréhension Python. 

Vous privilégierez un itérateur personnalisé à un générateur si vous avez besoin d’un objet gérant un état complexe ou si vous souhaitez exposer d’autres méthodes au-delà de __next__(), __iter__() et __init__(). À l’inverse, un générateur sera préférable pour traiter de grands volumes de données, puisqu’il ne stocke pas son contenu en mémoire, ou lorsqu’il n’est pas nécessaire d’implémenter un itérateur complet. 


Kurtis Pykes 's photo
Author
Kurtis Pykes
LinkedIn

FAQ

Quelle est la différence entre un itérateur et un générateur en Python ?

Un itérateur est tout objet qui implémente __iter__() et __next__(). Un générateur est un moyen plus simple de créer un itérateur via une fonction utilisant le mot-clé yield. Tous les générateurs sont des itérateurs, mais tous les itérateurs ne sont pas des générateurs.

Quand dois-je utiliser un générateur plutôt qu’une liste en Python ?

Utilisez un générateur pour des séquences longues ou infinies, ou lorsque l’efficacité mémoire est essentielle. Les listes conservent tous les éléments en mémoire, tandis que les générateurs produisent une valeur à la fois. Pour de petits jeux de données que vous réutiliserez, une liste convient généralement.

À quoi sert le mot-clé yield en Python ?

Le mot-clé yield transforme une fonction en générateur. Au lieu de retourner puis de quitter, yield met la fonction en pause, renvoie une valeur et mémorise son état pour reprendre à l’appel suivant.

Comment créer un générateur en Python ?

Écrivez soit une fonction qui utilise yield au lieu de return, soit une expression génératrice — même syntaxe qu’une compréhension de liste mais avec des parenthèses, par exemple (x * 2 for x in range(10)).

Les générateurs sont-ils plus rapides que les itérateurs en Python ?

Pas en vitesse brute, mais ils sont plus économes en mémoire car ils produisent les valeurs à la demande. Pour de grands jeux de données, cela se traduit souvent par de meilleures performances globales ; pour de petits volumes, la différence est négligeable.

Sujets

Meilleures formations Python

Cours

Python intermédiaire

4 h
1.4M
Mettez à niveau vos compétences en science des données en créant des visualisations à l'aide de Matplotlib et en manipulant des DataFrame avec pandas.
Afficher les détailsRight Arrow
Commencer le cours
Voir plusRight Arrow
Contenus associés

Tutoriel

Tutoriel sur les boucles Python

Tutoriel complet d'introduction aux boucles Python. Apprenez et pratiquez les boucles while et for, les boucles imbriquées, les mots-clés break et continue, la fonction range et bien plus encore.
Satyabrata Pal's photo

Satyabrata Pal

Tutoriel

Tutoriel sur la fonction range() en Python

Découvrez la fonction range() de Python et ses capacités à l'aide d'exemples.
Aditya Sharma's photo

Aditya Sharma

Tutoriel

Tutoriel Python : concaténation de chaînes de caractères

Découvrez différentes méthodes pour concaténer des chaînes de caractères en Python, avec des exemples illustrant chaque technique.
DataCamp Team's photo

DataCamp Team

Tutoriel

Tutoriel Python sur les structures de données

Initiez-vous aux structures de données de Python : apprenez-en plus sur les types de données et les structures de données primitives et non primitives, telles que les chaînes de caractères, les listes, les piles, etc.
Sejal Jaiswal's photo

Sejal Jaiswal

Tutoriel

Tutoriel et exemples sur les fonctions et méthodes des listes Python

Découvrez les fonctions et méthodes des listes Python. Veuillez suivre les exemples de code pour list() et d'autres fonctions et méthodes Python dès maintenant.
Abid Ali Awan's photo

Abid Ali Awan

Tutoriel

if…elif…else dans le tutoriel Python

Découvrez comment créer des instructions if…elif…else en Python.
DataCamp Team's photo

DataCamp Team

Voir plusVoir plus