L’une de mes fonctionnalités préférées en Python est la compréhension de collections. Elles peuvent sembler un peu obscures au début, mais lorsque vous les décomposez, elles sont en fait très simples.
Compréhension de liste
La clé pour comprendre les compréhensions de liste est qu’elles ne sont que des boucles for
sur une collection, exprimées dans une syntaxe plus concise et compacte. Prenons comme exemple la compréhension de liste suivante :
carres = [x * x for x in range(10)]
Elle calcule une liste de tous les nombres carrés entiers de 0 à 9 :
>>> carres[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Si nous voulions construire la même liste en utilisant une simple boucle for
, nous écririons probablement quelque-chose comme ceci :
carres = []for x in range(10): carres.append(x * x)
C’est une boucle assez simple. Maintenant, si nous essayons de généraliser une partie de cette structure, nous pourrions nous retrouver avec un modèle similaire à celui-ci :
valeurs = [ expression for element in collection ]
La compréhension de la liste ci-dessus est équivalente à la simple boucle for
suivante :
valeurs = []for element in collection: valeurs.append(expression)
Encore une fois, il s’agit d’un modèle assez simple que vous pouvez appliquer à la plupart des boucles for
. Il y a maintenant un autre élément utile que nous devons ajouter à ce modèle, et c’est le filtrage d’éléments avec des conditions.
Le filtrage d'éléments
Les compréhensions de liste peuvent filtrer les valeurs en fonction d’une condition arbitraire qui décide si la valeur résultante devient ou non une partie de la liste de sortie. Voici un exemple :
carres_entiers_pairs = [x * x for x in range(10) if x % 2 == 0]
Cette compréhension de liste calculera une liste des carrés de tous les entiers pairs de 0 à 9.
Si vous n’êtes pas familier avec ce que fait l’opérateur modulo (%
), il renvoie le reste après division d’un nombre par un autre. Dans cet exemple, l’opérateur %
nous donne un moyen simple de tester si un nombre est pair en vérifiant le reste après avoir divisé le nombre par 2.
>>> carres_entiers_pairs[0, 4, 16, 36, 64]
De la même manière que pour le premier exemple, cette nouvelle compréhension de liste peut être transformée en une boucle for
équivalente :
carres_entiers_pairs = []for x in range(10): if x % 2 == 0: carres_entiers_pairs.append(x * x)
Essayons de généraliser à nouveau la compréhension de la liste ci-dessus. Cette fois, nous allons ajouter une condition de filtre à notre modèle pour décider quelles valeurs se retrouveront dans la liste résultante.
Voici le modèle de compréhension de liste :
valeurs = [expression for element in collection if condition]
La compréhension de la liste ci-dessus est équivalente à la boucle for
suivante :
valeurs = []for element in collection: if condition: valeurs.append(expression)
Compréhension de sets et de dictionnaires
Python prend non seulement en charge les compréhensions de liste, mais a également une syntaxe similaire pour les sets et les dictionnaires.
Voici à quoi ressemble une compréhension de sets :
>>> { x * x for x in range(-9, 10) }set([64, 1, 36, 0, 49, 9, 16, 81, 25, 4])
Et maintenant une compréhension de dictionnaire :
>>> { x: x * x for x in range(5) }{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Les deux sont des outils utiles dans la pratique. De manière globale, il y a une mise en garde concernant les compréhensions en Python : à mesure que vous maîtrisez mieux leur utilisation, il devient de plus en plus facile d’écrire du code difficile à lire. Si vous ne faites pas attention, vous devrez peut-être bientôt faire face à des compréhensions monstrueuses de listes, de sets et de dictionnaires. N’oubliez pas que trop d’une bonne chose est généralement une mauvaise chose.
Personnellement, je trace la ligne rouge à ne pas franchir après deux boucles for
imbriquées pour la compréhension. Je trouve que dans la plupart des cas, il est préférable (comme dans “plus lisible” et “plus simple à maintenir”) d’utiliser des boucles for
classiques au-delà de ce point. Surtout qu’en termes de vitesse, la boucle for
classique est toujours plus rapide que la compréhension de liste pour faire la même chose.
Le mot de la fin
Pour résumer ce que nous venons de voir :
- Les compréhensions sont une caractéristique clé de Python. Les comprendre et les appliquer rendra votre code beaucoup plus Pythonique;
- Les compréhensions ne sont que de la syntaxe sophistiquée pour un modèle de boucle
for
simple. Une fois que vous aurez compris le modèle, vous développerez une compréhension intuitive pour les compréhensions ; - Il y a plus que de simples compréhensions de listes.
Si vous avez apprécié, n’hésitez pas à partager. Sinon les commentaires sont là pour vos remarques.
articles récents
Améliorer l’exploitation de votre projet Python avec un Makefile
Python ,
Modèles et Validation de données en Python avec Pydantic
Pydantic ,
Gagner de l’argent en programmant en Python
Python ,
Commentaires récents
- Christophe DELEUZE dans Qu’est-ce qu’un générateur en Python
- Max dans Qu’est-ce qu’un générateur en Python
- Johan dans Qu’est-ce qu’un générateur en Python