226 votes

Comment ajouter plusieurs arguments à une fonction map dont l'un reste inchangé ?

Supposons que nous ayons une fonction add comme suit

def add(x, y):
    return x + y

nous voulons appliquer la fonction map à un tableau

map(add, [1, 2, 3], 2)

La sémantique est que je veux ajouter 2 à chaque élément du tableau. Mais le map nécessite également une liste dans le troisième argument.

Remarque : Je mets le add par souci de simplicité. Ma fonction d'origine est beaucoup plus compliquée. Et bien sûr, il est possible de définir la valeur par défaut de y en add est hors de question car elle sera modifiée à chaque appel.

251voto

Sven Marnach Points 133943

L'une des options est la compréhension de la liste :

[add(x, 2) for x in [1, 2, 3]]

Plus d'options :

a = [1, 2, 3]

import functools
map(functools.partial(add, y=2), a)

import itertools
map(add, a, itertools.repeat(2, len(a)))

106voto

abarnert Points 94246

La documentation suggère explicitement qu'il s'agit de la principale utilisation de itertools.repeat :

Créer un itérateur qui renvoie l'objet encore et encore. S'exécute indéfiniment à moins que l'argument times ne soit spécifié. Utilisé comme argument de map() pour les paramètres invariants de la fonction appelée. Également utilisé avec zip() pour créer une partie invariante d'un enregistrement de tuple.

Et il n'y a pas de raison de passer len([1,2,3]) en tant que times argument ; map s'arrête dès que le premier itérable est consommé, de sorte qu'un itérable infini est parfaitement acceptable :

>>> from operator import add
>>> from itertools import repeat
>>> list(map(add, [1,2,3], repeat(4)))
[5, 6, 7]

En fait, cela équivaut à l'exemple de repeat dans les documents :

>>> list(map(pow, range(10), repeat(2)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Cela donne une solution agréable en langage fonctionnel paresseux qui est aussi parfaitement lisible en termes d'itérateurs Python.

44voto

larsmans Points 167484

Utiliser une liste de compréhension.

[x + 2 for x in [1, 2, 3]]

Si vous vraiment , vraiment , vraiment veulent utiliser map et lui donne une fonction anonyme comme premier argument :

map(lambda x: x + 2, [1,2,3])

29voto

Yi.ding Points 271

La carte peut contenir plusieurs arguments, la méthode standard est la suivante

map(add, a, b)

Dans votre question, il faut lire

map(add, a, [2]*len(a))

22voto

Simon Ndunda Points 631

La bonne réponse est plus simple que vous ne le pensez. Il suffit de faire :

map(add, [(x, 2) for x in [1,2,3]])

Et modifiez l'implémentation de l'ajout pour qu'il prenne un tuple, c'est-à-dire

def add(t):
   x, y = t
   return x+y

Cela permet de traiter tous les cas d'utilisation complexes où les deux paramètres d'ajout sont dynamiques.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X