Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 28

List Comprehensions: Concise Data Manipulation

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons exploré les tuples et les sets, complétant ainsi notre tour d'horizon des structures de données fondamentales de Python. Nous avons vu comment chaque structure (liste, dictionnaire, tuple, set) a des caractéristiques uniques qui la rendent idéale pour des tâches spécifiques.

Aujourd'hui, nous allons nous concentrer sur une technique extrêmement puissante et "Pythonique" pour travailler avec des listes : les list comprehensions (listes en compréhension). C'est une syntaxe concise et élégante pour créer des listes à partir d'autres collections. La maîtrise de cette technique est essentielle, car vous la rencontrerez très fréquemment dans les codes d'analyse de données et de machine learning pour sa lisibilité et son efficacité.

L'objectif de cette leçon est donc de vous apprendre à écrire des listes en compréhension pour créer et transformer des données de manière concise, en remplaçant des boucles for plus verbeuses.

1. De la boucle for à la liste en compréhension

Imaginez une tâche simple : vous voulez créer une liste contenant les carrés des dix premiers nombres entiers (0 à 9). La manière traditionnelle, que nous avons vue jusqu'à présent, consiste à utiliser une boucle for.




# Méthode traditionnelle avec une boucle for
squares = []  # 1. On initialise une liste vide
for number in range(10):  # 2. On parcourt une collection
    squares.append(number * number)  # 3. On ajoute l'élément transformé

print(squares)



# Résultat: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Ce code fonctionne parfaitement, mais il nécessite trois lignes pour une opération conceptuellement simple. Une liste en compréhension nous permet de faire la même chose en une seule ligne.




# La même opération avec une liste en compréhension
squares_comp = [number * number for number in range(10)]

print(squares_comp)



# Résultat: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Analysons la syntaxe. Une liste en compréhension est encadrée par des crochets [] et se compose de trois parties, que l'on peut lire presque comme une phrase en anglais :

[expression for item in iterable]

  1. expression (number * number) : C'est ce que vous voulez faire à chaque élément. C'est le résultat qui sera placé dans la nouvelle liste.
  2. for item in iterable (for number in range(10)) : C'est la boucle elle-même, qui parcourt la collection source.

C'est une simple réorganisation des éléments de la boucle for, mais elle met l'accent sur ce que l'on produit (expression) plutôt que sur la manière de le faire.

Learn Python LIST COMPREHENSIONS in 10 minutes! 📃

Cette courte vidéo de Bro Code explique très clairement cette transition d'une boucle traditionnelle à une liste en compréhension.

Regardez les deux premiers segments pour bien saisir la syntaxe de base et voir quelques exemples simples. Le premier segment, comparaison avec une boucle, montre la transformation directe. Le second, exemples de base, renforce le concept avec des multiplications et des carrés.


2. Ajouter une condition pour filtrer les données

Les listes en compréhension deviennent encore plus puissantes lorsque l'on y ajoute une condition pour filtrer les éléments de la collection source. Supposons que nous voulions créer une liste des carrés, mais uniquement pour les nombres pairs.

Avec une boucle for, nous ajouterions une instruction if :




# Boucle for avec un filtre
even_squares = []
for number in range(10):
    if number % 2 == 0:  # On ajoute une condition
        even_squares.append(number * number)

print(even_squares)



# Résultat: [0, 4, 16, 36, 64]

Pour faire de même avec une liste en compréhension, on ajoute simplement la condition à la fin :

[expression for item in iterable if condition]




# Liste en compréhension avec un filtre
even_squares_comp = [number * number for number in range(10) if number % 2 == 0]

print(even_squares_comp)



# Résultat: [0, 4, 16, 36, 64]
Cette image illustre parfaitement la conversion d'une boucle `for` avec une condition `if` en une liste en compréhension équivalente. Notez comment la structure reste logique : l'expression, la boucle, puis la condition.

List comprehensions 101 | Pydon't 🐍

Cet article de mathspp.com offre une excellente décomposition de la structure des listes en compréhension, avec des schémas très clairs.

Commencez par lire la section A loop that builds a list pour revoir la transformation de base. Ensuite, lisez la section Filtering data pour comprendre comment l'instruction if s'intègre. L'auteur y suggère même de l'écrire sur plusieurs lignes pour plus de clarté, ce qui est une excellente pratique.


3. Transformation conditionnelle (if/else)

Que se passe-t-il si vous ne voulez pas filtrer des éléments, mais plutôt appliquer une transformation différente en fonction d'une condition ? Par exemple, remplacer tous les nombres négatifs par 0 et garder les positifs tels quels.

Ici, la syntaxe change légèrement. La condition (avec if et else) se place avant la boucle for.

[valeur_si_vrai if condition else valeur_si_faux for item in iterable]

prices = [10, -5, 22, -8, 15]




# Remplacer les prix négatifs par 0
adjusted_prices = [price if price > 0 else 0 for price in prices]

print(adjusted_prices)



# Résultat: [10, 0, 22, 0, 15]

Cette forme est extrêmement utile pour le nettoyage de données, une tâche courante en machine learning.

When to Use a List Comprehension in Python

L'article de Real Python explique très bien cette distinction entre le filtrage (if à la fin) et la transformation conditionnelle (if/else au début).

Dans la section "Supercharging Your Python List Comprehensions", concentrez-vous sur la partie qui commence par le placement de la condition. Portez une attention particulière à l'exemple avec original_prices.


4. Une perspective mathématique

Étant donné votre formation universitaire en mathématiques, vous pourriez apprécier de voir les listes en compréhension sous un autre angle. Elles sont directement inspirées de la notation de construction d'ensembles (set-builder notation) que vous avez peut-être rencontrée.

En mathématiques, pour définir l'ensemble des carrés des nombres de 0 à 9, on pourrait écrire :

Cette notation se lit : "S est l'ensemble des tels que est un élément de l'ensemble {0, ..., 9}".

Regardez la ressemblance avec la syntaxe Python :
squares = [n**2 for n in range(10)]

La structure est presque identique. Cette analogie peut vous aider à solidifier votre compréhension du concept.

List comprehensions 101 | Pydon't 🐍

L'article de mathspp.com explore cette connexion en détail.

Pour approfondir cette analogie, lisez la section intitulée List comprehensions from first principles.


5. Exercices pratiques

Mettons maintenant cela en pratique. Essayez de résoudre ces problèmes en utilisant des listes en compréhension.

Exercice 1 : Normalisation de données
Vous avez une liste de noms de villes mal formatés. Créez une nouvelle liste où chaque nom de ville est en minuscules et sans espaces superflus au début ou à la fin. (Rappel : les méthodes de chaîne .lower() et .strip() seront utiles).

cities = ["   Paris", "MARSEILLE  ", "  lyon", "TOULOUSE"]




# Votre code ici
# formatted_cities = ...




# print(formatted_cities)

Exercice 2 : Extraction et filtrage
Vous avez une liste de phrases. Créez une liste contenant la longueur de chaque phrase, mais uniquement pour les phrases qui contiennent plus de 20 caractères.

sentences = [
    "C'est une phrase courte.",
    "Voici une phrase un peu plus longue pour tester le filtre.",
    "Python est puissant.",
    "Les listes en compréhension rendent le code très lisible et concis."
]




# Votre code ici
# long_sentence_lengths = ...




# print(long_sentence_lengths)

Solution de l'exercice 1 :

formatted_cities = [city.strip().lower() for city in cities]
print(formatted_cities) # ['paris', 'marseille', 'lyon', 'toulouse']

Solution de l'exercice 2 :

long_sentence_lengths = [len(s) for s in sentences if len(s) > 20]
print(long_sentence_lengths) # [58, 65]

6. Quand être prudent

Bien que puissantes, les listes en compréhension ne sont pas toujours la solution idéale. Voici deux points à garder à l'esprit :

  1. Lisibilité : Si votre logique devient trop complexe (plusieurs conditions if, des transformations imbriquées), une boucle for traditionnelle sur plusieurs lignes sera souvent plus facile à lire et à maintenir. La concision ne doit pas se faire au détriment de la clarté.
  2. Effets de bord (Side Effects) : Une liste en compréhension doit être utilisée pour créer une nouvelle liste. Évitez de l'utiliser pour des actions qui ne contribuent pas à la création de la liste, comme print() ou la modification d'une autre variable. C'est un anti-pattern.



# Mauvaise pratique : ne pas utiliser une liste en compréhension juste pour une boucle
# [print(x) for x in range(5)]




# Bonne pratique : utiliser une boucle for standard pour cela
for x in range(5):
    print(x)

Conclusion

Félicitations ! Vous avez découvert l'une des caractéristiques les plus appréciées et les plus idiomatiques de Python. Savoir quand et comment utiliser les listes en compréhension rendra votre code non seulement plus court, mais aussi plus expressif et souvent plus rapide.

Points clés à retenir :

  • Les listes en compréhension offrent une syntaxe concise pour créer des listes à partir d'itérables.
  • La syntaxe de base est [expression for item in iterable].
  • On peut y ajouter un filtre avec if à la fin : [... if condition].
  • On peut réaliser une transformation conditionnelle avec if/else au début : [val_si_vrai if condition else val_si_faux for ...].
  • Privilégiez toujours la lisibilité : si une liste en compréhension devient trop complexe, une boucle for est préférable.

Dans notre prochaine leçon, nous aborderons un autre aspect fondamental du travail avec des données : la lecture et l'écriture de fichiers texte. Cela nous permettra de commencer à charger des données depuis des sources externes pour les traiter avec les outils que nous apprenons.