Python : compréhension des intensions en 1 minute

par Christophe Combelles, mis à jour le 19/05/2013
L'intension, par opposition à extension et qu'on appelle aussi compréhension, est en Python une technique de construction des données composites qui se rapproche un peu de certains langages fonctionnels, et qui permet d'écrire du code qui sera considéré comme plus « pythonique », donc plus court, plus lisible et en bonus, plus rapide.

Exemple

Prenons l'exemple de la liste des sept premières lettres de l'alphabet.  On peut l'écrire en extension, c'est à dire en donnant l'ensemble de ses éléments, ce qui s'appelle aussi une écriture littérale :
['a', 'b', 'c', 'd', 'e', 'f', 'g']
On peut aussi construire cette liste de manière automatique avec un bout de code et des boucles, par exemple en utilisant les fonctions primitives chr( ) et ord( ) et sachant que chr(97) donne 'a' et ord('a') donne 97.
letters = []
num = ord('a')
while len(letters) < 7:
letters.append(chr(num))
num += 1
La même chose en code pythonique, en utilisant une liste en intension (ou list comprehension) donnerait ça :
[chr(num) for num in range(ord('a'), ord('a')+7)]

L'intérêt est mutiple :

  • On voit tout de suite qu'on est en train de construire une liste, et c'est plus lisible
  • Ça prend 1 ligne et ça peut être intégré dans une expression
  • À l'exécution c'est plus rapide qu'une boucle

Les trois types d'intensions

Il existe trois types de constructions similaires :

La list comprehension qui construit une liste:
[truc for i in iterable]
Le set comprehension qui construit un set:
{truc for i in iterable}
Le dict comprehension qui construit un dict :
{cle: valeur for i in iterable}
Pour chacun on peut rajouter une condition à la fin:
[truc for i in iterable if condition]
{
truc for i in iterable if condition}
{
cle: valeur for i in iterable if condition}

Ci-dessus, truc, iterable, condition, cle et valeur peuvent elles-même être des expressions, donc on peut faire des intensions dans les intensions et des constructions assez complexes. Mais il ne pas trop en abuser quand-même, sous peine de pénaliser à nouveau la lisibilité...

Post-scriptum

Il existe encore une autre syntaxe, avec des parenthèses, qui construit un générateur :

(truc for i in iterable)

L'objet renvoyé possède une méthode next( ) qui renvoie l'élément suivant à chaque appel. Ceci est utile pour les listes infinies ou trop consommatrices de mémoire.