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.

17voto

Carles Sala Points 1769

J'ai parfois résolu des situations similaires (comme l'utilisation de pandas.apply ) en utilisant la méthode fermetures

Pour les utiliser, vous devez définir une fonction qui définit et renvoie dynamiquement une enveloppe pour votre fonction, faisant ainsi de l'un des paramètres une constante.

Voici ce qu'il en est :

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

def add_constant(y):
    def f(x):
        return add(x, y)
    return f

Ensuite, add_constant(y) renvoie une fonction qui peut être utilisée pour ajouter y à une valeur donnée :

>>> add_constant(2)(3)
5

Ce qui permet de l'utiliser dans toutes les situations où les paramètres sont donnés un par un :

>>> map(add_constant(2), [1,2,3])
[3, 4, 5]

éditer

Si vous ne voulez pas avoir à écrire la fonction de fermeture ailleurs, vous avez toujours la possibilité de la construire à la volée à l'aide d'une fonction lambda :

>>> map(lambda x: add(x, 2), [1, 2, 3])
[3, 4, 5]

14voto

jterrace Points 21939

Si vous en disposez, j'envisagerais d'utiliser numpy. Il est très rapide pour ce type d'opérations :

>>> import numpy
>>> numpy.array([1,2,3]) + 2
array([3, 4, 5])

Cela suppose que votre application réelle effectue des opérations mathématiques (qui peuvent être vectorisées).

11voto

Todor Points 5347

Si vous avez vraiment besoin d'utiliser la fonction map (comme mon devoir de classe ici...), vous pouvez utiliser une fonction enveloppante avec 1 argument, en passant le reste à la fonction originale dans son corps ; c'est-à-dire :

extraArguments = value
def myFunc(arg):
    # call the target function
    return Func(arg, extraArguments)

map(myFunc, itterable)

Sale et moche, mais toujours efficace

8voto

Shqi.Yang Points 91

Je pense que starmap est ce qu'il vous faut :

from itertools import starmap

def test(x, y, z):
    return x + y + z

list(starmap(test, [(1, 2, 3), (4, 5, 6)]))

6voto

Yuukio Points 189
def func(a, b, c, d):
 return a + b * c % d

map(lambda x: func(*x), [[1,2,3,4], [5,6,7,8]])

En enveloppant l'appel de fonction d'une lambda et en utilisant le star unpack, vous pouvez faire du map avec un nombre arbitraire d'arguments.

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