web-dev-qa-db-fra.com

Utilisation de la fonction map () avec des arguments de mots clés

Voici la boucle sur laquelle j'essaie d'utiliser la fonction map:

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
for volume_id in volume_ids:
    my_function(volume_id, ip=ip)

Est-ce qu'il y a un moyen de faire ça? Ce serait trivial s'il n'y avait pas le paramètre ip, mais je ne suis pas sûr de savoir comment gérer cela.

31
Cameron Sparr

Utilisez functools.partial() :

from functools import partial

mapfunc = partial(my_function, ip=ip)
map(mapfunc, volume_ids)

partial() crée un nouvel appelable, qui appliquera tous les arguments (y compris les arguments de mots clés) à la fonction encapsulée, en plus de tout ce qui est transmis à ce nouvel appelable.

65
Martijn Pieters

Voici une approche lambda (pas meilleure, juste différente)

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
map(lambda ids: my_function(ids, ip), volume_ids);
11
Jason Sperske

Cela peut être fait facilement avec une compréhension de la liste.

volume_ids = [1,2,3,4,5]
ip = '172.12.13.122'
results = [my_function(i,ip=ip) for i in volume_ids]
5
shapr

En général, on peut utiliser map pour passer des mots-clés à une fonction en encapsulant cette fonction dans quelque chose qui décompresse un dictionnaire, puis en transmettant une liste de dictionnaires à une carte. Exemple:

from itertools import product

volume_ids = [1,2,3,4,5]
volume_ids = (("volume_id", volume_id) for volume_id in volume_ids)
ips = [("ip", '172.12.13.122')]
kwargs_iterable = map(dict, product(volume_ids, ips))

result = map(lambda kwargs: my_function(**kwargs), kwargs_iterable)

Pour votre cas particulier, cependant, une solution plus simple serait:

map(my_function, volume_ids, [ip]*len(volume_ids))

Ceci est concis et ne repose sur aucune importation. Une autre possibilité pourrait être de combiner le produit et la feuille de calcul d’itertools:

from itertools import product, starmap

ips = [ip]
starmap(my_function, product(volume_ids, ips))

Ceci se généralise bien au paramètre avec plus d'une adresse IP ou plus de deux variables.

1
Jonas Dahlbæk

Que dis-tu de ça?

results = []
for volume_id in volume_ids:
    results.append(my_function(volume_id, ip=ip))

Il s’agit de trois lignes de code au lieu d’un - c’est trois lignes de code clair et évident au lieu d’importer un utilitaire spécial du module tel ou tel. Cet argument est probablement une question de goût, mais il a beaucoup de poids selon qui vous parlez.

0
Armin Rigo