Historique de la question
La fonction map() vient de la programmation fonctionnelle (déjà présente dans Lisp), son but est d'appliquer une fonction à chaque élément d'une séquence tout en renvoyant un nouvel objet itérable avec les résultats. En Python, elle est apparue bien avant l'arrivée des expressions génératrices et des expressions de liste, mais elle est toujours largement utilisée, en particulier dans les grands pipelines de traitement de données.
Problème
Lorsque vous devez modifier chaque élément d'une collection selon certaines règles, les solutions de type for deviennent rapidement encombrantes et moins lisibles. Les expressions de liste et map() permettent d'exprimer l'intention de manière compacte. Il est important de comprendre les différences entre ces approches pour choisir le bon outil.
Solution
map(func, iterable) crée un itérateur paresseux où les éléments de la séquence d'origine sont transformés par la fonction funcmap ne calcule pas immédiatement les éléments, il fonctionne de manière paresseusedef square(x): return x * x squares = map(square, [1, 2, 3]) print(list(squares)) # [1, 4, 9]
L'expression de liste [square(x) for x in [1, 2, 3]] fait la même chose, mais renvoie immédiatement une liste, tandis que l'expression génératrice (square(x) for x in [1, 2, 3]) est un générateur paresseux.
Caractéristiques clés :
Map() renvoie-t-il une liste en Python 3 ?
Non, à partir de Python 3, map() ne renvoie pas une liste mais un itérateur paresseux. Pour obtenir une liste, il faut envelopper le résultat dans list().
res = map(str.upper, ['a', 'b']) print(res) # <map object ...> print(list(res)) # ['A', 'B']
Peut-on utiliser map() pour ajouter une condition de filtrage dans la fonction ?
Non, map() ne filtre pas les éléments, il ne fait que les transformer. Pour le filtrage, utilisez filter() ou une expression de liste :
result = map(str.upper, ['a', 'b', None]) # Si None est passé, map lèvera une erreur d'appel str.upper(None) # filter aidera à supprimer None avant map
Peut-on parcourir deux séquences en même temps avec map() ?
Oui, map() peut accepter un nombre arbitraire de séquences, et la fonction de transformation doit accepter autant d'arguments :
x = [1, 2, 3] y = [10, 20, 30] result = map(lambda a, b: a + b, x, y) print(list(result)) # [11, 22, 33]
Le développeur s'attend à obtenir une liste immédiatement :
mapped = map(abs, [-1, -2, -3]) print(mapped[1]) # TypeError: 'map' object is not subscriptable
Avantages :
Inconvénients :
Utilisation d'une expression génératrice pour le filtrage et de map() pour la transformation :
nums = range(-5, 6) positives = (x for x in nums if x > 0) sq = map(lambda n: n * n, positives) print(list(sq)) # [1, 4, 9, 16, 25, 36]
Avantages :
Inconvénients :