16.4. La mutation de liste revisitée

Vous avez déjà vu comment appliquer les list comprehensions aux mutations de listes. Il y a une autre manière d'obtenir la même chose en utilisant la fonction prédéfinie map. Elle fonctionne de manière similaire à la fonction filter.

Exemple 16.10. Présentation de map

>>> def double(n):
...     return n*2
...     
>>> li = [1, 2, 3, 5, 9, 10, 256, -3]
>>> map(double, li)                       1
[2, 4, 6, 10, 18, 20, 512, -6]
>>> [double(n) for n in li]               2
[2, 4, 6, 10, 18, 20, 512, -6]
>>> newlist = []
>>> for n in li:                          3
...     newlist.append(double(n))
...     
>>> newlist
[2, 4, 6, 10, 18, 20, 512, -6]
1 map prend une fonction et une liste[9] et retourne une nouvelle liste en appelant la fonction avec chaque élément de la liste dans l'ordre. Dans ce cas, la fonction multiplie simplement chaque élément par 2.
2 Vous pouvez accomplir la même tâche avec une list comprehension. Les list comprehensions ont été introduite pour la première fois dans Python 2.0, map en a toujours fait partie.
3 Vous pouvez, si vous insistez pour penser comme un programmeur Visual Basic, utiliser une boucle for pour accomplir la même tâche.

Exemple 16.11. map avec des listes de types mélangés

>>> li = [5, 'a', (2, 'b')]
>>> map(double, li)                       1
[10, 'aa', (2, 'b', 2, 'b')]
1 Je précise que map fonctionne tout à fait avec des listes de types mélangés, tant que la fonction que vous utilisez est capable de traiter chaque type. Dans ce cas, la fonction double multiplie simplement l'argument qui lui est passé par 2 et Python A Le Bon Réflexe et agit en fonction du type de l'argument. Pour les entiers, cela veut dire les multiplier effectivement par 2, pour les chaînes, les concaténer avec elles-mêmes, pour les tuples, en créer un nouveau contenant deux fois la série d'éléments du précédent.

Mais passons maintenant à du véritable code.

Exemple 16.12. map dans regression.py

    filenameToModuleName = lambda f: os.path.splitext(f)[0] 1
    moduleNames = map(filenameToModuleName, files)          2
1 Comme vous l'avez vu dans la Section 4.7, «Utiliser des fonctions lambda», lambda définit une fonction incluse. Et comme vous l'avez vu dans l'Exemple 6.17, «Division de noms de chemins», os.path.splitext prend un nom de fichier et retourne un tuple (nom, extension). Donc filenameToModuleName est une fonction qui prend un nom de fichier et en supprime l'extension, ne retournant que le nom.
2 L'appel de map prend chaque nom de fichier de files, le passe à la fonction filenameToModuleName et retourne une liste des valeurs de retour de chacun de ces appels de fonction. Autrement dit, on enlève l'extension de chaque nom de fichier et on stocke la liste de ces noms sans extension dans moduleNames.

Comme vous le verrez dans le reste de ce chapitre, vous pouvez étendre ce type d'approche centrée sur les données jusqu'au but final, qui est de définir et d'exécuter une suite de teste unique contenant les tests de toutes les suites individuelles.

Footnotes

[9] Encore une fois, il faut préciser que map peut prendre une liste, un tuple ou un objet quelconque agissant comme une séquence. Voir la note précédente au sujet de filter.