Python et la compréhension de liste : exemples

Python 3000, la prochaine version de Python, va supprimer un certain nombre de primitives pourtant bien utiles, tels que map() et filter(). A la place, la solution recommandée est l'utilisation des "list comprehension", où en francais, compréhension de liste. Wikipedia nous propose cette définition :

Une liste, comme un ensemble, peut-être définie par la donnée d'une propriété caractéristique de ses éléments, on dit qu'on l'a définie en compréhension. Comme cette construction offre des avantages de lisibilité et de concision, certains langages de programmation proposent donc la possibilité de définir une liste par une propriété caractéristique et l'on appelle cela la compréhension de liste.

Avant de débuter avec les exemples, voici la grammaire des compréhension de liste en Python telle qu'elle est donnée dans la documentation :

test 	 	::=  	and_test ( "or" and_test )* | lambda_form
testlist 	::= 	test ( "," test )* [ "," ]
list_display 	::= 	"[" [listmaker] "]"
listmaker 	::= 	expression ( list_for | ( "," expression )* [","] )
list_iter 	::= 	list_for | list_if
list_for 	::= 	"for" expression_list "in" testlist [list_iter]
list_if 	::= 	"if" test [list_iter]

Exemple 1 : équivalence à map :

Trouver les 10 premières puissances de 2, avec map :

map(lambda x: 2**x, xrange(10))

Avec la compréhension de listes :

[2**x for x in xrange(10)]

Exemple 2 : équivalence à filter :

Trouver les nombres pairs parmis les nombres de 0 à 9, avec filter() :

filter(lambda x:x%2 == 0, xrange(10))

Avec la compréhension de listes :

[x for x in xrange(10) if x%2==0]

Exemple 3 : les deux à la fois :

Trouver la puissance de deux des nombres pairs de 0 à 9 (oui c'est totalement inutile), avec map() et filter() :

map(lambda x:2**x, filter(lambda x:x%2==0, xrange(10)))

Et avec les compréhension de listes :

[2**x for x in xrange(10) if x%2==0]

Un peu plus compréhensible non ?

Exemple 4 : Renvoyer plusieurs résultats

On reprend l'exemple des puissances de deux, mais on veut renvoyer cette fois ci, à la fois le nombre calculé, et sa puissance :

[(x, 2**x) for x in xrange(10)]

Et avec un for pour gérer l'affichage :

for n, v in [(x, 2**x) for x in xrange(10)]:
     print "2^%s = %s" % (n, v)

Résultat :

2^0 = 1 2^1 = 2 2^2 = 4 2^3 = 8 2^4 = 16 2^5 = 32 2^6 = 64 2^7 = 128 2^8 = 256 2^9 = 512

Pratique !

J'utilise Escaline 
!