Compréhension de liste
Apprenez la syntaxe des compréhensions de liste Python, le filtrage, les boucles imbriquées, les compréhensions de dict et de set, et quand les utiliser.
Compréhension de liste Python
La compréhension de liste est un moyen concis de construire une nouvelle liste en appliquant une expression à chaque élément d'un itérable — en filtrant optionnellement des éléments avec une condition — le tout en une seule ligne lisible. Cette page couvre la syntaxe complète, les modèles courants, les compréhensions de dict et de set, et des conseils sur le moment où une boucle for classique est le meilleur choix.
Syntaxe
La forme générale d'une compréhension de liste est :
new_list = [expression for item in iterable if condition]| Partie | Rôle |
|---|---|
expression | Valeur placée dans la nouvelle liste pour chaque item |
item | Variable de boucle, prend chaque valeur de iterable à tour de rôle |
iterable | Toute séquence ou itérable : liste, tuple, string, range, etc. |
if condition | Filtre optionnel — seuls les éléments où la condition est True sont inclus |
La partie if condition est optionnelle. Lorsqu'elle est omise, chaque élément de l'itérable produit une entrée dans la nouvelle liste.
Exemple de base : mise au carré de nombres
La boucle for équivalente nécessite trois lignes ; la compréhension de liste fait la même chose en une seule :
Filtrage avec une condition
Ajoutez une clause if après l'itérable pour ne conserver que les éléments qui satisfont une condition :
Vous pouvez combiner n'importe quel prédicat. Par exemple, conserver les mots de plus de quatre caractères :
words = ['hi', 'hello', 'world', 'python', 'ai']
long_words = [w for w in words if len(w) > 4]
print(long_words) # ['hello', 'world', 'python']if/else dans l'expression (ternaire)
Lorsque vous avez besoin de transformer chaque élément mais d'appliquer une logique différente selon une condition, placez le if/else dans la partie expression (avant for), et non après l'itérable :
numbers = range(1, 6)
labels = ['even' if x % 2 == 0 else 'odd' for x in numbers]
print(labels) # ['odd', 'even', 'odd', 'even', 'odd']Notez la différence :
[expr for x in it if cond]— filtre : ignore les éléments oùcondestFalse[a if cond else b for x in it]— transformation : chaque élément produit une valeur, choisie parcond
Travailler avec des chaînes de caractères
La compréhension de liste fonctionne sur tout itérable, y compris les chaînes de caractères et les listes de chaînes :
words = ['hello', 'world', 'python']
upper_words = [w.upper() for w in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']Extraire les caractères individuels qui satisfont une condition :
vowels = [ch for ch in 'programming' if ch in 'aeiou']
print(vowels) # ['o', 'a', 'i']Boucles imbriquées
La compréhension de liste prend en charge plusieurs clauses for, équivalent à des boucles imbriquées. Le for le plus à gauche est la boucle externe :
Un cas d'utilisation courant des compréhensions de liste imbriquées est l'aplatissement d'une liste 2D (matrice) en une liste 1D :
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]Conseil de lecture : développez mentalement les compréhensions imbriquées comme des boucles for imbriquées dans le même ordre de gauche à droite.
Compréhension de dictionnaire
La même idée s'applique aux dictionnaires en utilisant {} avec une expression clé: valeur :
keys = ['a', 'b', 'c']
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)}
print(mapping) # {'a': 1, 'b': 2, 'c': 3}Inverser les clés et les valeurs dans un dictionnaire existant :
original = {'name': 'Alice', 'city': 'Paris'}
inverted = {v: k for k, v in original.items()}
print(inverted) # {'Alice': 'name', 'Paris': 'city'}Compréhension d'ensemble
Utilisez {} avec une expression unique (sans deux-points) pour construire un ensemble, qui supprime automatiquement les doublons :
numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16}Le résultat est non ordonné (les ensembles n'ont pas d'ordre garanti), donc ne vous fiez pas à la séquence affichée.
Performance
Les compréhensions de liste sont généralement plus rapides que les boucles for équivalentes qui appellent .append(), car l'interpréteur peut optimiser la boucle interne en C. Pour mesurer le temps d'exécution de votre propre code, utilisez le module timeit :
import timeit
loop_time = timeit.timeit(
'result = []\nfor x in range(1000):\n result.append(x**2)',
number=10000
)
comp_time = timeit.timeit(
'[x**2 for x in range(1000)]',
number=10000
)
print(f'Loop: {loop_time:.3f}s')
print(f'Comprehension: {comp_time:.3f}s')
# Comprehension is typically 20-40% fasterL'avantage en performance diminue ou disparaît lorsque l'expression elle-même est lente (E/S réseau, calcul intensif). Profilez avant d'optimiser.
Quand utiliser une boucle for classique à la place
La compréhension de liste n'est pas toujours le bon outil :
| Situation | Préférer |
|---|---|
| Transformation ou filtre unique | Compréhension de liste |
| Multiples effets de bord par itération (journalisation, mutation d'état) | Boucle for |
| Logique complexe nécessitant plusieurs instructions | Boucle for |
| Compréhensions profondément imbriquées (plus de deux niveaux) | Boucle for — la lisibilité prime |
| Le résultat n'est jamais stocké (vous avez seulement besoin d'itérer) | Expression génératrice ((x for x in ...)) |
Le signal le plus clair pour revenir à une boucle for est lorsque vous vous retrouvez à plisser les yeux sur la compréhension pour comprendre ce qu'elle fait.
Pièges courants
La fuite de variables n'existe pas en Python 3. La variable de boucle dans une compréhension est limitée à la portée de la compréhension elle-même :
x = 'original'
result = [x * 2 for x in range(3)]
print(x) # 'original' — not overwritten by the comprehension's xÉvitez les compréhensions profondément imbriquées. Plus de deux clauses for dans une seule compréhension nuit à la lisibilité pour peu de bénéfices. Découpez-les en listes intermédiaires nommées ou en boucles for.
Les expressions génératrices économisent de la mémoire. Si vous avez seulement besoin d'itérer sur le résultat une fois (par exemple, le passer à sum() ou max()), remplacez [] par () pour obtenir un générateur qui produit les éléments un à la fois :
total = sum(x ** 2 for x in range(1, 1001))
print(total) # 333833500