cours1 min de lecture

Listes en compréhension

La notation `[expression for x in itérable]` — construire un tableau en une ligne, directement inspiré du langage mathématique.
programme

Introduction

En mathématiques, on définit volontiers un ensemble en compréhension par une formule du type :

E={x2x{0,1,2,3,4}}E = \{\, x^2 \mid x \in \{0, 1, 2, 3, 4\} \,\}

qui se lit « l'ensemble des x2x^2 pour xx parcourant {0,1,2,3,4}\{0, 1, 2, 3, 4\} ». Python propose une notation très proche pour les listes, baptisée liste en compréhension. Elle permet de construire un tableau en une seule ligne, lisible et concise.

C'est l'une des deux capacités explicitement listées par : construire un tableau par compréhension.

Le cœur du concept

La syntaxe générale est :

[<expression> for <variable> in <itérable>]

Le mécanisme : Python parcourt chaque élément de l'itérable (souvent un range ou une autre liste), évalue l'expression en y substituant la variable, et collecte les résultats dans une nouvelle liste.

Exemple fondateur : les carrés

carres = [x ** 2 for x in range(10)]
print(carres)
# Sortie : [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Lecture : « les x2x^2 pour xx allant de 00 à 99 ». C'est l'équivalent exact, en plus compact, de la boucle :

carres = []
for x in range(10):
    carres.append(x ** 2)
La version en compréhension est strictement équivalente à la version boucle. Vous choisissez selon la lisibilité : courte, préférez la compréhension ; complexe avec plusieurs traitements, préférez la boucle classique.

Variations utiles

Compréhension avec transformation

L'expression peut être n'importe quoi de calculable.

doubles = [2 * n for n in range(1, 6)]
print(doubles)
# Sortie : [2, 4, 6, 8, 10]

majuscules = [mot.upper() for mot in ["chat", "chien", "lapin"]]
print(majuscules)
# Sortie : ['CHAT', 'CHIEN', 'LAPIN']

Compréhension à partir d'une liste existante

notes = [12, 15, 8, 17, 11]
bonus = [n + 2 for n in notes]
print(bonus)
# Sortie : [14, 17, 10, 19, 13]

Que produit 3 * k for k in range(4) ?

Compréhension avec condition

On peut filtrer les éléments retenus en ajoutant if <condition> à la fin.

Syntaxe :

[<expression> for <variable> in <itérable> if <condition>]

Filtrer les pairs

pairs = [x for x in range(10) if x % 2 == 0]
print(pairs)
# Sortie : [0, 2, 4, 6, 8]

Lecture : « les xx pour xx allant de 00 à 99, si xx est pair ».

Conserver les notes au-dessus de la moyenne

notes = [12, 15, 8, 17, 11]
au_dessus = [n for n in notes if n >= 12]
print(au_dessus)
# Sortie : [12, 15, 17]

Combiner transformation et filtre

L'expression et le filtre coexistent : Python filtre puis applique l'expression.

carres_pairs = [x ** 2 for x in range(10) if x % 2 == 0]
print(carres_pairs)
# Sortie : [0, 4, 16, 36, 64]

Que produit n for n in 1, 4, 7, 10, 13 if n > 5 ?

Compréhension imbriquée — construire une matrice

Une compréhension peut servir d'expression à une autre. C'est l'idiome classique pour fabriquer une matrice.

# Matrice 3×3 remplie de zéros
m = [[0 for j in range(3)] for i in range(3)]
print(m)
# Sortie : [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

Lecture, de l'extérieur vers l'intérieur :

  • l'expression extérieure construit 3 lignes (for i in range(3)) ;
  • chaque ligne est elle-même [0 for j in range(3)], donc 3 zéros.

Variante avec la table de multiplication :

table = [[i * j for j in range(4)] for i in range(4)]
print(table)
# Sortie : [[0, 0, 0, 0],
#          [0, 1, 2, 3],
#          [0, 2, 4, 6],
#          [0, 3, 6, 9]]
⏵ Ctrl+↵ pour exécuter
Aucune exécution pour l'instant.

Pièges courants

  • Oublier les crochets extérieurs : x ** 2 for x in range(10) seul est une erreur de syntaxe. La liste en compréhension a besoin de ses crochets [ ].
  • Confondre l'ordre for / if : la condition vient après le for, pas avant.
  • Vouloir tout faire en compréhension : si l'expression dépasse une ligne claire, repassez à une boucle for lisible.

Vérification de compréhension

Que vaut x + 1 for x in range(5) if x % 2 == 1 ?