3.6. Mutation de listes

Une des caractéristiques les plus puissantes de Python est la list comprehension (création fonctionnelle de listes) qui fournit un moyen concis d'appliquer une fonction sur chaque élément d'une liste afin d'en produire une nouvelle.

Exemple 3.24. Présentation des list comprehensions

>>> li = [1, 9, 8, 4]
>>> [elem*2 for elem in li]      1
[2, 18, 16, 8]
>>> li                           2
[1, 9, 8, 4]
>>> li = [elem*2 for elem in li] 3
>>> li
[2, 18, 16, 8]
1 Pour comprendre cette ligne, observez là de droite à gauche. li est la liste que vous appliquez. Python la parcourt un élément à la fois, en assignant temporairement la valeur de chacun des éléments à la variable elem. Python applique ensuite la fonction elem*2 et ajoute le résultat à la liste retournée.
2 Notez que les list comprehensions ne modifient pas la liste initiale.
3 Vous pouvez assigner le résultat d'une list comprehension à la variable que vous traitez. Python assemble la nouvelle liste en mémoire et assigne le résultat à la variable une fois la transformation terminée.

Voici les list comprehensions dans la fonction buildConnectionString que nous avons déclaré au Chapitre 2:

["%s=%s" % (k, v) for k, v in params.items()]

Notez tout d'abord que vous appelez la fonction items du dictionnaire params. Cette fonction retourne une liste de tuples avec toutes les données stockées dans le dictionnaire.

Exemple 3.25. Les fonctions keys, values et items

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> params.keys()   1
['server', 'uid', 'database', 'pwd']
>>> params.values() 2
['mpilgrim', 'sa', 'master', 'secret']
>>> params.items()  3
[('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]
1 La méthode keys d'un dictionnaire retourne la liste de toutes les clés. Cette liste ne suit pas l'ordre dans lequel le dictionnaire a été défini (souvenez-vous, les éléments d'un dictionnaire ne sont pas ordonnés) mais cela reste une liste.
2 La méthode values retourne la liste de toutes les valeurs. La liste est dans le même ordre que celle retournée parkeys, on a donc params.values()[n] == params[params.keys[n]] pour toute valeur de n.
3 La méthode items retourne une liste de tuples de la forme (clé, valeur). La liste contient toutes les données stockées dans le dictionnaire.

Voyons maintenant ce que fait buildConnectionString. Elle prends une liste, param.items(), et crée une nouvelle liste en appliquant une instruction de formatage de chaîne à chacun de ses éléments. La nouvelle liste aura le même nombre d'éléments que params.items() mais chaque élément sera une chaîne qui contient à la fois une clé et la valeur qui lui est associée dans le dictionnaire params.

Exemple 3.26. List comprehensions dans buildConnectionString, pas à pas

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> params.items()
[('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]
>>> [k for k, v in params.items()]                1
['server', 'uid', 'database', 'pwd']
>>> [v for k, v in params.items()]                2
['mpilgrim', 'sa', 'master', 'secret']
>>> ["%s=%s" % (k, v) for k, v in params.items()] 3
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
1 Notez que nous utilisons deux variables pour parcourir la liste params.items(). Il s'agit d'un autre usage de l'assignment multiple. Le premier élément de params.items() est ('server', 'mpilgrim'), donc lors de la première itération de la transformation, k va prendre la valeur 'server' et v la valeur 'mpilgrim'. Dans ce cas, nous ignorons la valeur de v et placons uniquement la valeur de k dans la liste résultante. Cette transformation correspond donc au comportement de params.keys(). (Vous n'utiliseriez pas réellement une list comprehension comme ceci dans du vrai code; il s'agit d'un exemple exagérément simple pour que vous compreniez ce qui se passe.)
2 Nous faisons la même chose ici, mais nous ignorons la valeur de k de telle sorte que le résultat est équivalent à celui de params.values().
3 En combinant les deux exemples précédent avec le formatage de chaîne, nous obtenons une liste de chaînes comprenant la clé et la valeur de chaque élément du dictionnaire. Cela ressemble étonnament à la sortie du programme, tout ce qui reste à faire maintenant est la jointure des éléments de cette liste en une seule chaîne.

Pour en savoir plus sur les list comprehensions