Une page de Le Lab de la taverne

Comprendre les List Comprehension Python

Par Darko Stankovski, 02/04/2020 (Mise à jour 18/05/2026) — Débutant

Apprendre un langage ne se limite pas à apprendre une syntaxe. Un langage a ses idiomes, ses structures, ses particularités. Ainsi, Python propose des outils qui vont permettre de se faciliter la vie pour certaines choses. Les créateurs du langage ont délibérément choisi de proposer des outils simplifiant les tâches redondantes, celles que l’on fait régulièrement.

Ainsi, il y a en programmation quelque chose que nous faisons régulièrement avec les listes (les collections de manières générale) :

  • Rechercher un élément
  • Transformer les éléments de la liste
  • Filtrer la liste, c’est à dire supprimer les éléments qui ne nous intéressent pas.

Dans ce billet, je vais vous présenter un outil qui facilite la vie pour les deux derniers usages : transformer et filtrer une liste. Cet outil, c’est les list comprehension ou, en Français, listes en intension (non, il n’y a pas de faute d’orthographe).

Dans ce tuto, vous verrez :

  • Le concept des list comprehension
  • Leur usage pour transformer les données d'une liste
  • Leur usage pour filtrer les données d'une liste

La donnée de départ

Le concept de list comprehension en anglais ou compréhension de liste en français nécessite une donnée de départ qui est n'importe quel itérable. Le concept est illustré avec, comme données de départ, des listes car c'est le plus simple mais c'est la notion d'itérable qui est importante. Vous pourrez donc les utiliser avec d'autres séquences mais aussi des générateurs.

Pour le contexte de ce tuto, ma donnée sera donc la liste suivante qui me permet de gérer les films Harry Potter. Chaque film est représenté par un tuple comportant dans l’ordre le titre du film, sa durée en minutes et un booléen indiquant si je l’ai vu ou non.

movies = [("The Philosopher's Stone", 152, True),
          ("The Chamber of Secrets", 161, True),
          ("The Prisoner of Azkaban", 142, False),
          ("the Goblet of Fire", 157, True),
          ("the Order of the Phoenix", 138, False),
          ("the Half-Blood Prince", 153, True),
          ("the Deathly Hallows – Part 1", 126, False),
          ("the Deathly Hallows – Part 2", 130, False)]

Transformer une liste

Transformer une liste c’est, à partir d’une liste, créer une nouvelle liste en transformant chaque donnée. Une formulation algorithmique serait :

Soit une liste l1 contenant n données

Soit une fonction f1(d) -> d' qui transforme une donnée d en d'

Nous devons obtenir une liste l2 de n données où chaque donnée à l'indice i de l2 correspond à la transformation par f1 de la donnée à l'indice i de l1.

À partir de la liste de films, je souhaite obtenir une liste ne comportant que les titres des films. C’est une transformation de chaque élément de la liste movies vers une liste de chaines de caractères. De manière classique, vous allez écrire le code suivant :

titles = []

for movie in movies:
    titles.append(movie[0])

Ça fait le job et vous avez une nouvelle liste de chaines de caractères.

En utilisant une compréhension de liste

Structure d’une compréhension de liste

La list comprehension va nous permettre de simplifier cette écriture. La syntaxe en pseudo-code de la transformation est la suivante :

[transformation for element in iterable]

Il s’agit bien d’appliquer une transformation sur chaque élément d’un itérable.

Mise en œuvre de la transformation

Dans notre cas, notre code devient :

titles = [movie[0] for movie in movies]

Et c’est tout. Pas besoin de définir une liste vide ni d'écrire l'itération, la structure crée la donnée que nous récupérons dans une variable.

La magie n’est pas de faire tenir le code en une seule ligne mais également de le rendre lisible. De faire comprendre l’intention à la première lecture. Là où avec une structure for classique, vous ne savez pas à quoi sert l'itération, lorsque vous soyez cette structure, vous devez tout de suite comprendre qu’il s’agit d’une transformation.

Filtrer une liste

Une variante de la transformation est le filtre. Filtrer une liste consiste à créer une liste L2 à partir d’une liste L1 dont les éléments sont les éléments de L1 correspondant à un critère c.

Reprenons notre liste movies, le dernier élément indique si j’ai vu le film. Je souhaite générer une liste des films que je n’ai pas encore vu, ceux pour lesquels le dernier élément est à False.

Le code classique est le suivant :

movies_to_see = []

for movie in movies:
    if not movie[-1]:
        movies_to_see.append(movie)

Ça fait aussi le job, vous avez une liste de tuples qui correspond au critère. Mais là aussi nous pouvons utiliser une compréhension de liste en lui ajoutant une condition selon ce principe :

[transformation for element in iterable if condition]

Et notre implémentation est :

movies_to_see = [movie for movie in movies if not movie[-1]]

Et j'ai ma liste de films qui me reste à voir. Bien évidemment, nous pouvons transformer et filtrer dans la même expression.

Transformer et filtrer

Pour obtenir une liste des titres des films qui me reste à voir, il suffit de combiner les deux actions précédentes et le code devient :

titles_to_see = [movie[0]
                 for movie in movies
                 if not movie[-1]]

À nouveau, le but n’est pas de faire du one-liner mais bien de faciliter la lecture de l’intention du code. Si vous voyez une list comprehension, vous devez comprendre qu’il s’agit d’une transformation et/ou un filtre de la liste. C'est pour cela que je favorise cette écriture en 3 lignes : transformation, itération et condition si présente. Cela me permet d'identifier l'intention à la simple structure du code.

Améliorer la lisibilité

Le code précédent fait le job mais si j'insiste sur la lisibilité, il peut encore être amélioré. Nous allons utiliser la propriété de l’unpacking qui permet en Python, lors d’une affectation, de déclarer autant de variables que d’élément de la collection à affecter. La conséquence est que chaque élément de la collection est affecté à la variable du même ordre. En conséquence, nous pouvons écrire la list comprehension de la manière suivante :

titles_to_see = [title
                 for title, _, seen in movies
                 if not seen]

Relisez bien cette ligne si nécessaire à haute voix. Vous comprenez maintenant l’intérêt de nommer correctement ses variables ?

En parlant de nommer ses variables, j’utilise ici une convention qui se développe peu à peu en nommant une variable _ soit en utilisant uniquement le caractère souligné. Ce nom ne veut rien dire ? C’est exacte, c’est le but. Cette convention part du principe qu’un code ne doit déclarer que des variables que si c’est utile. Or la durée ne nous sert à rien dans ce code. Mais la structure de l’unpacking nous oblige à déclarer une variable pour recevoir cette seconde donnée de la liste.

La convention est donc qu’ici, j’informe le lecteur que je reçois une donnée qui n’a aucun intérêt pour mon code. Il n’a pas à se demander quand et pourquoi je l’utilise, elle ne sert à rien.

Les compréhension de listes dans un flux

Extraire des données d’éléments d’une liste pour en faire autre chose est une opération courante. D’ailleurs, à partir de la liste movies, nous pouvons calculer la durée totale (en minutes) de l’ensemble des films Harry Potter. Pour cela, nous pouvons utiliser la fonction sum(iterable) en lui fournissant une liste d’entier. L’instruction est alors simplement :

total_duration = sum([duration for _, duration, _ in movies])

Vous voyez que les compréhension de listes permettent de simplifier le code Python afin d’en faciliter la lecture. En guise d’exercice, écrivez l’instruction qui permet de calculer la durée des épisodes qui me reste à voir.

La difficulté pour bien mettre en œuvre les list comprehension, c’est de bien comprendre ce qu’est une transformation. Pour illustrer cela, je vous préparer un autre article pour bientôt.

Licence Creative Commons

Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Pas de Modification 4.0 International