Les compréhensions sont probablement la construction la plus emblématique de Python. Elles permettent d'écrire en une ligne ce qui demanderait 4 ou 5 lignes avec une boucle classique. Maîtrisées au TOSA Avancé, elles font la différence entre un débutant et un Pythoniste.
Le principe
Vous avez déjà utilisé ce pattern dans la Partie 2, sans qu'on le nomme :
# Pattern classique : boucle + append
notes = [12, 15, 9, 17, 11]
carres = []
for n in notes:
carres.append(n ** 2)
print(carres)La compréhension de liste exprime la même chose en une ligne :
notes = [12, 15, 9, 17, 11]
carres = [n ** 2 for n in notes]
print(carres)C'est plus court, plus lisible, et plus rapide (optimisations internes de Python).
Anatomie d'une compréhension
[ expression for element in iterable if condition ]
└────┬────┘ └────────┬──────────┘ └─────┬──────┘
transforme parcourt chaque filtreLes trois parties :
expression: ce qu'on produit pour chaque élément retenu.for element in iterable: d'où viennent les éléments.if condition(optionnelle) : garde seulement les éléments vérifiant la condition.
Compréhensions de liste
Forme basique : transformer
nombres = [1, 2, 3, 4, 5]
# Doubler
doubles = [n * 2 for n in nombres]
print(doubles)
# Carrés
carres = [n ** 2 for n in nombres]
print(carres)
# Conversion de types
chaines = [str(n) for n in nombres]
print(chaines)Avec filtrage : if
nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Seulement les pairs
pairs = [n for n in nombres if n % 2 == 0]
print(pairs)
# Pairs multipliés par 10
pairs_x10 = [n * 10 for n in nombres if n % 2 == 0]
print(pairs_x10)
# Chaînes non vides
mots = ["Alice", "", "Bob", " ", "Charlie"]
non_vides = [m for m in mots if m.strip()]
print(non_vides)Avec expression conditionnelle (ternaire)
On peut placer une ternaire dans l'expression (attention, ce n'est plus un filtre !) :
notes = [12, 15, 9, 17, 7, 11]
# Étiqueter chaque note
mentions = ["admis" if n >= 10 else "recalé" for n in notes]
print(mentions)Compréhensions imbriquées (2 for)
On peut chaîner plusieurs for pour produire toutes les combinaisons :
# Produit cartésien
couleurs = ["rouge", "vert"]
tailles = ["S", "M", "L"]
combinaisons = [f"{c}-{t}" for c in couleurs for t in tailles]
print(combinaisons)Équivalent à deux boucles imbriquées :
combinaisons = []
for c in couleurs:
for t in tailles:
combinaisons.append(f"{c}-{t}")Aplatir une liste de listes
Un idiome classique :
matrice = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
aplatie = [x for ligne in matrice for x in ligne]
print(aplatie)