nums = [1, 2, 3, 4, 5]
squares = []
for n in nums:
squares.append(n ** 2)
squares[1, 4, 9, 16, 25]
if à la finif/else avant le forRemplacez la plupart de vos boucles par une seule ligne lisible qui construit la collection sur place.
Apprenez les compréhensions Python — de liste, de dictionnaire et d’ensemble — en transformant une boucle for en une seule expression. Couvre le filtrage avec if, les valeurs conditionnelles, les compréhensions imbriquées, et les cas où une expression génératrice (ou une simple boucle) est le meilleur choix. Chaque bloc s’exécute et affiche son résultat.
26 juin 2026
7 juillet 2026
[f(x) for x in items] fait ce qu’une boucle for avec .append() fait — en une seule ligne lisible.[...] construit une liste, {k: v ...} un dictionnaire, {...} un ensemble. Apprenez la forme liste et les autres suivent.if à la fin pour filtrer ; placez if/else avant le for pour choisir une valeur. Deux tâches différentes, deux positions différentes — les confondre est le bug classique du débutant.for. La clarté l’emporte sur l’astuce.Vous recourez constamment à une boucle : parcourir une liste, transformer chaque élément, collecter les résultats. En Python, ce motif — démarrer une liste vide, boucler, .append() — est si courant que le langage vous offre un raccourci en une ligne pour cela : la compréhension.
Une compréhension dit « construis cette collection à partir de celle-là » en une seule expression. Elle se lit presque comme la phrase que vous diriez à voix haute — « le carré de chaque nombre dans nums » devient [n**2 for n in nums]. Une fois le déclic fait, vous écrirez moins de boucles, avec moins de code répétitif à mal écrire (pas de liste vide à oublier, pas d’index à mal gérer).
Cette leçon montre toujours la boucle d’abord, puis la compréhension qui la remplace, pour que vous voyiez la correspondance exacte. Ensuite elle couvre le filtrage, les compréhensions de dictionnaire et d’ensemble, les générateurs (le cousin économe en mémoire), et — tout aussi important — quand ne pas utiliser de compréhension du tout.
Chaque résultat sur cette page est réel — et vous pouvez l’exécuter vous-même sans rien installer : cliquez sur Try ▸ sous n’importe quel bloc pour l’exécuter en direct dans votre navigateur (Python démarre au premier Run, puis c’est instantané).
Voici le motif dans sa forme la plus simple. Nous voulons les carrés de quelques nombres. La méthode avec boucle : créer une liste vide, parcourir l’entrée, ajouter chaque valeur transformée.
Trois lignes de gestion — la liste vide, l’en-tête de boucle, l’ajout — pour exprimer une seule idée : mettre au carré chaque nombre. La compréhension replie ces trois lignes en une seule expression. Lisez-la de droite à gauche au début : for n in nums est la boucle, n ** 2 est ce que vous collectez.
Même résultat, une seule ligne, et l’intention est en surface. La forme générale est :
EXPRESSION est ce que chaque élément de sortie doit être ; ITEM est la variable de boucle ; ITERABLE est ce que vous parcourez. Tout ce que vous pouvez parcourir avec for fonctionne ici — une liste, une chaîne, un range, un fichier, les clés d’un dictionnaire.
['DATA', 'NOVIA', 'PYTHON']
L’expression peut être n’importe quelle fonction de l’élément, y compris un appel de méthode comme w.upper() ci-dessus.
if à la finSouvent vous ne voulez pas tous les éléments — seulement ceux qui passent un test. La boucle ajoute un if à l’intérieur du corps. Ici nous gardons uniquement les nombres pairs.
Dans une compréhension, le filtre va à la fin, après le for. Lisez-le comme « n pour chaque n dans nums, si n est pair » :
La forme est maintenant :
Un if final décide si un élément apparaît ou non. Les éléments qui échouent au test sont simplement ignorés — la sortie est plus courte que l’entrée. Vous pouvez combiner le filtrage avec une transformation : garder les pairs et les mettre au carré.
if/else avant le forIl y a un deuxième usage, différent, de if — choisir quelle valeur produire, tout en gardant chaque élément. C’est une expression conditionnelle (A if test else B), et elle va dans l’emplacement de l’expression, avant le for. Ici nous étiquetons chaque nombre « even » ou « odd » — la sortie a la même longueur que l’entrée.
['odd', 'even', 'odd', 'even', 'odd']
Sous forme de compréhension, le "even" if ... else "odd" complet se place là où va l’expression :
Remarquez les deux positions et ce qu’elles signifient :
if à la fin, sans else : élimine des éléments. « …s’il est pair. »if/else au début : garde chaque élément, choisit sa valeur. « …pair ou impair. »Si Python se plaint de la syntaxe d’un conditionnel dans une compréhension, c’est presque toujours parce que le if est au mauvais endroit pour ce que vous vouliez dire. Filtrez à la fin ; choisissez au début.
La même idée construit un dictionnaire — vous produisez simplement une paire key: value au lieu d’une valeur unique, et vous l’entourez de {}. La version avec boucle construit un dictionnaire vide et y affecte les valeurs.
{'data': 4, 'novia': 5, 'python': 6}
La compréhension énonce la paire directement : w: len(w) for each w.
La forme reflète celle de la liste, avec une expression key: value :
Un motif courant consiste à transformer deux listes parallèles en un dictionnaire, en les appariant avec zip() :
{'Ada': 'analyst', 'Linus': 'engineer', 'Grace': 'admiral'}
Le filtrage fonctionne exactement comme avant — un if final. Ici nous gardons uniquement les mots longs :
Utilisez {} avec une seule expression (sans deux-points) pour construire un ensemble — les résultats uniques, sans doublons, sans ordre. C’est la façon naturelle de collecter des valeurs distinctes. La version avec boucle utilise un ensemble et .add().
{'i', 'm', 'p', 's'}
La compréhension tient en une ligne, et la déduplication est automatique — "mississippi" a de nombreuses répétitions mais l’ensemble ne garde chaque lettre qu’une fois.
Une compréhension d’ensemble brille quand vous transformez et voulez l’unicité en une seule étape — ici, les longueurs de mots distinctes :
Quatre mots ont une longueur de 4 ou 6, mais l’ensemble ne rapporte chaque longueur distincte qu’une fois.
Vous pouvez boucler deux fois dans une seule compréhension. Les deux clauses for se lisent de gauche à droite, de l’extérieur vers l’intérieur — le même ordre que si vous imbriquiez les boucles. Ici nous aplatissons une liste de lignes en une seule liste.
[1, 2, 3, 4, 5, 6, 7, 8, 9]
La compréhension garde le même ordre for row ... for value :
Celle-là se lit bien. Mais l’imbrication vous pousse vers des lignes que personne ne pourra analyser une semaine plus tard. Une règle empirique : si vous avez besoin de plus d’un for, ou d’un for plus un if délicat, arrêtez-vous et demandez-vous si une simple boucle se lit mieux. C’est généralement le cas — la boucle a la place de nommer les étapes intermédiaires et de respirer. Les compréhensions sont un outil de clarté ; dès qu’elles nuisent à la lisibilité, elles ont cessé de faire leur travail.
Une compréhension de liste construit la liste entière en mémoire d’un seul coup. Pour quelques milliers d’éléments, ce n’est rien. Pour des millions — ou un flux sans fin — c’est un problème. Remplacez les crochets par des parenthèses et vous obtenez une expression génératrice : elle produit les éléments un à la fois, à la demande, ne gardant que l’élément courant.
nums = range(1, 1_000_001) # one million numbers
# List comprehension — builds a 1,000,000-element list in memory
squares_list = [n ** 2 for n in nums]
# Generator expression — builds nothing yet; yields on demand
squares_gen = (n ** 2 for n in nums)
print(type(squares_list), "len:", len(squares_list))
print(type(squares_gen))<class 'list'> len: 1000000
<class 'generator'>
La liste est entièrement matérialisée ; le générateur n’est qu’une recette — aucune liste d’un million d’éléments n’existe tant que quelque chose ne demande pas les valeurs. C’est tout l’intérêt : quand vous avez seulement besoin de consommer les valeurs une fois (souvent pour alimenter un agrégat), le générateur n’alloue jamais la liste.
333333833333500000
Quand vous passez une expression génératrice comme unique argument à une fonction comme sum(), max(), ou any(), vous pouvez même supprimer les parenthèses supplémentaires — sum(n ** 2 for n in ...) se lit clairement.
Le compromis : un générateur est à usage unique et non indexable. Vous pouvez le parcourir une fois ; il n’y a pas de gen[3] ni de len(gen). Si vous avez besoin d’un accès aléatoire, du décompte, ou de boucler plus d’une fois, construisez une liste. Si vous parcourez des valeurs une seule fois — surtout des grandes — utilisez un générateur.
Les compréhensions servent à construire une collection. Quand ce n’est pas ce que vous faites, une boucle est le choix honnête. Recourez à une boucle for classique quand :
[print(x) for x in items]) construit une liste jetable de None et masque l’intention. Bouclez simplement.break anticipé, l’accumulation d’un état. Les compréhensions ne peuvent pas faire break et n’ont pas de place pour des variables intermédiaires.Voici le cas des effets de bord bien fait — une boucle, parce que nous faisons quelque chose par élément, sans collecter de résultats :
Ada: 95 -> pass
Linus: 60 -> review
Grace: 88 -> pass
C’est plus clair que n’importe quelle ligne unique. Le savoir-faire n’est pas d’utiliser des compréhensions partout — c’est de connaître la seule tâche pour laquelle elles excellent et d’utiliser une boucle pour le reste.
Collez une boucle for que vous avez écrite et demandez à Prova « réécris ceci sous forme de compréhension » — elle replie la liste vide, la boucle et le .append() en une seule expression, filtrant à la fin ou choisissant une valeur au début selon ce que votre code veut dire. Parce que le runtime est juste ici, vous exécutez les deux et vérifiez qu’ils produisent le même résultat avec loop_result == comp_result, de sorte que vous faites confiance à la réécriture plutôt que d’accepter une réponse plausible sur parole. The runtime is the judge. Demander à Prova →
Les blocs ci-dessus ont été exécutés au moment de la génération. Modifiez celui-ci et appuyez sur Run pour essayer les compréhensions par vous-même — il s’exécute dans votre navigateur via Pyodide (sans installation). Ou cliquez sur Try ▸ sous n’importe quel bloc ci-dessus pour y déposer son code.
Une compréhension de liste sur des données volumineuses dévore la mémoire. [expensive(x) for x in millions] alloue la liste entière avant que vous ne touchiez un seul élément. Si vous ne parcourez les résultats qu’une fois — pour sum(), max(), écrire dans un fichier, ou alimenter une autre boucle — utilisez une expression génératrice (parenthèses) pour que les valeurs circulent une à la fois et que rien ne soit stocké. Revenez à une liste seulement quand vous avez besoin de l’indexation, de la longueur, ou de plus d’un passage.
Le if est au mauvais endroit. Un if final (après le for) filtre — il élimine des éléments. Un if/else dans l’emplacement de l’expression (avant le for) choisit une valeur et garde chaque élément. [x for x in xs if x > 0] garde les positifs ; [x if x > 0 else 0 for x in xs] remplace les négatifs par 0. Un simple if/else placé à la fin est une SyntaxError ; un filtre placé au début aussi. Décidez d’abord : filtrer ou choisir ?
S’attendre à ce qu’une variable de boucle fuie à l’extérieur. En Python 3, la variable de compréhension est limitée à la compréhension — après [n for n in range(5)], il ne reste aucun n dans le code environnant (contrairement à une simple boucle for, dont la variable persiste). Ne comptez pas sur la lecture de la « dernière valeur » de la variable d’une compréhension ; elle n’est pas là.
Évitez la compréhension quand vous ne construisez pas une collection. Si le corps de la boucle a des effets de bord (afficher, écrire des fichiers, journaliser), a besoin de plusieurs instructions (un try/except, plusieurs affectations), utilise break/continue, ou que chaque itération dépend de la précédente (un total cumulé), une simple boucle for est plus claire et l’outil adapté. Les compréhensions servent à transformer une collection en une autre — quand ce n’est pas l’objectif, ne forcez pas.
Une compréhension de liste ([...]) construit la liste entière en mémoire d’un seul coup ; une expression génératrice ((...)) ne construit rien au départ et produit les valeurs une à la fois au fur et à mesure que vous itérez. La liste est réutilisable et indexable (xs[3], len(xs)) ; le générateur est à usage unique, non indexable, et n’utilise presque pas de mémoire. Utilisez une liste quand vous avez besoin d’un accès aléatoire, du décompte, ou de plusieurs passages ; utilisez un générateur pour des données volumineuses ou en flux que vous parcourez une fois — par exemple sum(x**2 for x in big).
Il y en a deux sortes. Pour filtrer (éliminer certains éléments), placez if CONDITION à la fin : [x for x in xs if x > 0]. Pour choisir une valeur tout en gardant chaque élément, placez une expression conditionnelle dans l’emplacement de début : [x if x > 0 else 0 for x in xs]. La position est la règle — un if final filtre ; un if/else en tête choisit une valeur.
Oui — même syntaxe, crochets différents. {k: v for ...} (avec un deux-points) construit un dictionnaire ; {expr for ...} (sans deux-points) construit un ensemble de résultats uniques ; [expr for ...] construit une liste. Ainsi {w: len(w) for w in words} crée un dictionnaire des longueurs de mots, et {len(w) for w in words} crée l’ensemble des longueurs distinctes.
Généralement un peu — une compréhension évite la recherche répétée de l’attribut .append() et exécute davantage de son travail en bytecode optimisé, donc elle est souvent modestement plus rapide que la boucle explicite équivalente. Mais l’écart est faible ; choisissez une compréhension pour la lisibilité, pas pour la vitesse brute. Pour un travail numérique vraiment lourd, une bibliothèque vectorisée comme NumPy bat les deux.
Travaillez chaque tâche dans la cellule Essayez en direct ci-dessus — modifiez et exécutez.
On vous donne ce code. Réécrivez chaque bloc sous forme de compréhension appropriée (liste, dictionnaire ou ensemble).
nums = [3, -1, 4, -1, 5, -9, 2, 6]
# 1. The squares of only the positive numbers (a list)
pos_squares = []
for n in nums:
if n > 0:
pos_squares.append(n ** 2)
# 2. A label per number: "pos" or "neg", keeping all of them (a list)
labels = []
for n in nums:
labels.append("pos" if n > 0 else "neg")
# 3. The distinct absolute values (a set)
abs_vals = set()
for n in nums:
abs_vals.add(abs(n))Le bloc 1 filtre, donc if va à la fin. Le bloc 2 choisit une valeur pour chaque élément, donc le if/else va dans l’emplacement de l’expression, avant le for. Le bloc 3 veut l’unicité, donc utilisez une compréhension d’ensemble {...}.
Le if du bloc 1 filtre à la fin ; le if/else du bloc 2 choisit une valeur au début ; le {...} du bloc 3 réduit les doublons (-1 apparaît deux fois mais 1 n’arrive qu’une fois dans l’ensemble).
Vous devez calculer la somme de n ** 2 pour n de 1 à dix millions, et vous n’utilisez le résultat qu’une fois. Devriez-vous écrire sum([n ** 2 for n in range(1, 10_000_001)]) ou sum(n ** 2 for n in range(1, 10_000_001)), et pourquoi ?
Une version construit une liste de dix millions d’éléments en mémoire avant de sommer. L’autre produit les valeurs une à la fois. Vous consommez les valeurs exactement une fois.
Utilisez l’expression génératrice : sum(n ** 2 for n in range(1, 10_000_001)). La forme avec compréhension de liste construit une liste de dix millions d’éléments en mémoire juste pour la jeter après la somme. Le générateur produit chaque carré à la demande, donc sum() les additionne un à la fois et rien n’est stocké. Comme vous ne parcourez les valeurs qu’une fois, vous n’avez jamais besoin de la liste.
Vous voulez uniquement les nombres pairs de nums. Quelle compréhension est correcte ?
A. [n if n % 2 == 0 else None for n in nums] — une valeur conditionnelle B. [n for n in nums if n % 2 == 0] — un filtre final C. {n: n % 2 == 0 for n in nums} — un dictionnaire
B. Un if final filtre — il garde uniquement les éléments qui passent, donc vous obtenez juste les pairs. A garde chaque élément, remplaçant les impairs par None (une valeur conditionnelle, pas un filtre). C construit un dictionnaire associant chaque nombre à True/False, pas une liste filtrée. Pour éliminer des éléments, placez if à la fin sans else.
Une compréhension est une boucle for qui construit une collection, écrite comme une seule expression — [f(x) for x in items], avec {k: v ...} pour les dictionnaires et {...} pour les ensembles. Ajoutez un if final pour filtrer, un if/else en tête pour choisir des valeurs, et passez aux parenthèses pour un générateur quand la mémoire compte. Gardez-les peu profondes et utilisez-les pour construire des collections ; quand le corps fait un vrai travail ou plusieurs étapes, une simple boucle est le choix le plus clair.
À voir aussi : DataFrames pandas — mettez la même idée de transformation-sur-une-collection au travail sur de vraies données tabulaires. · La famille apply de R — la même idée « faire ceci à chaque élément », à la manière de R.
@online{2026,
author = {},
title = {Compréhensions Python : compréhensions de liste, de
dictionnaire et d’ensemble},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/programming/python-foundations/comprehensions},
langid = {fr}
}