Chapitre 17 : Compréhensions de Liste
Syntaxe, Performance, Conditions
1. Quoi : Les Compréhensions de Liste
Une compréhension de liste (list comprehension) est une syntaxe concise et élégante pour créer une nouvelle liste à partir d'un itérable existant. C'est l'une des fonctionnalités les plus appréciées et les plus "pythonic" du langage.
Elle combine une boucle for et la création d'un nouvel élément en une seule ligne.
2. Pourquoi : Un code plus lisible et plus rapide
Comparer la méthode classique avec une compréhension de liste :
Méthode classique (avec une boucle for)
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n * n)
# squares est maintenant [1, 4, 9, 16, 25]
Méthode avec une compréhension de liste
numbers = [1, 2, 3, 4, 5]
squares = [n * n for n in numbers]
# squares est maintenant [1, 4, 9, 16, 25]
Les avantages sont clairs :
- Concise : Moins de lignes de code.
- Lisible : La syntaxe est très proche de la description en langage naturel : "crée une liste de
n*npour chaquendansnumbers". - Performante : Elle est souvent plus rapide qu'une boucle
foréquivalente, car elle est optimisée en C dans l'interpréteur Python.
3. Comment : La Syntaxe
La syntaxe de base est : [<expression> for <element> in <iterable>]
<expression>: L'opération à appliquer à chaque élément pour créer le nouvel élément.<element>: La variable temporaire qui représente chaque élément de l'itérable.<iterable>: La séquence source (liste, tuple, range, etc.).
# Mettre en majuscules une liste de noms
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
# Résultat : ['ALICE', 'BOB', 'CHARLIE']
# Obtenir la longueur de chaque mot
words = ["hello", "world", "python"]
lengths = [len(word) for word in words]
# Résultat : [5, 5, 6]
Ajout d'une condition if
On peut ajouter une condition if à la fin pour filtrer les éléments de l'itérable source.
Syntaxe : [<expression> for <element> in <iterable> if <condition>]
Méthode classique
numbers = [1, 2, 3, 4, 5, 6]
even_squares = []
for n in numbers:
if n % 2 == 0: # Condition de filtre
even_squares.append(n * n)
# even_squares est [4, 16, 36]
Avec une compréhension de liste
numbers = [1, 2, 3, 4, 5, 6]
even_squares = [n * n for n in numbers if n % 2 == 0]
# even_squares est [4, 16, 36]
Description en langage naturel : "crée une liste de n*n pour chaque n dans numbers si n est pair".
Ajout d'une expression conditionnelle (if/else)
Que faire si vous voulez appliquer une expression différente selon une condition ? On utilise alors l'opérateur ternaire if/else avant la boucle for.
Syntaxe : [<expr_si_vrai> if <condition> else <expr_si_faux> for <element> in <iterable>]
Exemple : Créer une liste qui indique si chaque nombre est "pair" ou "impair".
numbers = [1, 2, 3, 4, 5]
labels = ["even" if n % 2 == 0 else "odd" for n in numbers]
# labels est ['odd', 'even', 'odd', 'even', 'odd']
Description en langage naturel : "crée une liste avec 'even' si n est pair, sinon 'odd', pour chaque n dans numbers".
4. Au-delà des listes
La même syntaxe peut être utilisée pour créer d'autres types de collections :
-
Compréhensions d'ensemble (
set) : Pour créer un ensemble (garantit l'unicité).numbers = [1, 2, 2, 3, 1]
unique_squares = {n * n for n in numbers}
# Résultat : {1, 4, 9} -
Compréhensions de dictionnaire (
dict) : Pour créer un dictionnaire.names = ["Alice", "Bob", "Charlie"]
name_lengths = {name: len(name) for name in names}
# Résultat : {'Alice': 5, 'Bob': 3, 'Charlie': 7}
5. Quand ne PAS les utiliser ?
Les compréhensions de liste sont puissantes, mais il ne faut pas en abuser.
- Évitez les compréhensions trop complexes : Si votre compréhension de liste devient très longue, avec plusieurs boucles
forimbriquées ou une logiqueif/elsecompliquée, une bouclefortraditionnelle sera plus lisible. - N'utilisez pas de compréhension de liste si vous n'avez pas besoin de créer une liste : Si vous voulez juste exécuter une action pour chaque élément (comme un
print), utilisez une bouclefornormale. Une compréhension de liste qui n'est pas assignée à une variable crée une liste en mémoire pour rien.
✅ Règle générale : Si c'est concis et lisible, utilisez une compréhension. Si ça devient confus, revenez à une boucle for.
Exercices :
Exercice 17 - Filtrage et Transformation de Données
Objectif
Cet exercice a pour but de vous faire utiliser les compréhensions de liste pour filtrer et transformer des données de manière concise, en appliquant une condition if et une expression.
Contexte
Vous avez une liste de dictionnaires, chaque dictionnaire représentant un produit avec son nom et son prix. Vous devez effectuer deux tâches :
- Extraire uniquement les noms des produits qui coûtent moins de 50.
- Créer une nouvelle liste de produits où une réduction de 10% est appliquée à chaque produit, en ajoutant une clé
discounted_price.
Énoncé
-
Créez un nouveau fichier Python nommé
product_filter.py. -
Initialisez la liste de produits suivante :
products = [
{"name": "Laptop", "price": 1200},
{"name": "Mouse", "price": 25},
{"name": "Keyboard", "price": 75},
{"name": "Monitor", "price": 300},
{"name": "Webcam", "price": 45},
]
Tâche 1 : Filtrer les produits abordables
- En utilisant une compréhension de liste avec une condition
if, créez une nouvelle liste nomméeaffordable_product_names. - Cette liste doit contenir uniquement les noms (
name) des produits dont lepriceest strictement inférieur à 50. - Affichez le résultat.
Tâche 2 : Appliquer une réduction
- En utilisant une compréhension de dictionnaire (ou une compréhension de liste qui crée des dictionnaires), créez une nouvelle liste nommée
discounted_products. - Chaque élément de cette nouvelle liste doit être un dictionnaire contenant le
namedu produit et un nouveau champdiscounted_pricequi correspond au prix original moins 10%. - Affichez le résultat. Pour une meilleure lisibilité, vous pouvez afficher un produit par ligne.
Résultat Attendu
Affordable Products (< $50):
['Mouse', 'Webcam']
Products with 10% discount:
{'name': 'Laptop', 'discounted_price': 1080.0}
{'name': 'Mouse', 'discounted_price': 22.5}
{'name': 'Keyboard', 'discounted_price': 67.5}
{'name': 'Monitor', 'discounted_price': 270.0}
{'name': 'Webcam', 'discounted_price': 40.5}
Cliquez ici pour voir un exemple de code de solution
# product_filter.py
products = [
{"name": "Laptop", "price": 1200},
{"name": "Mouse", "price": 25},
{"name": "Keyboard", "price": 75},
{"name": "Monitor", "price": 300},
{"name": "Webcam", "price": 45},
]
# --- Tâche 1: Filtrer ---
# [ <expression> for <element> in <iterable> if <condition> ]
# L'expression est p['name']
# L'élément est p
# L'itérable est products
# La condition est p['price'] < 50
affordable_product_names = [p["name"] for p in products if p["price"] < 50]
print("Affordable Products (< $50):")
print(affordable_product_names)
# --- Tâche 2: Transformer ---
print("\nProducts with 10% discount:")
# [ <expression> for <element> in <iterable> ]
# L'expression est un nouveau dictionnaire
# L'élément est p
# L'itérable est products
discounted_products = [
{"name": p["name"], "discounted_price": p["price"] * 0.9} for p in products
]
# Affichage plus lisible
for product in discounted_products:
print(product)