Using map() function with keyword arguments

2019-01-08 16:40发布

问题:

Here is the loop I am trying to use the map function on:

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

Is there a way I can do this? It would be trivial if it weren't for the ip parameter, but I'm not sure how to deal with that.

回答1:

Use functools.partial():

from functools import partial

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

partial() creates a new callable, that'll apply any arguments (including keyword arguments) to the wrapped function in addition to whatever is being passed to that new callable.



回答2:

Here is a lambda approach (not better, just different)

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


回答3:

This can be done easily with a list comprehension.

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


回答4:

In general, one can use map to pass keywords to a function by wrapping that function in something which unpacks a dictionary, and then passing an iterable of dictionaries to map. Example:

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)

For your special case, however, a simpler solution would be:

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

This is concise and does not rely on any imports. Another possibility could be to combine product and starmap from itertools:

from itertools import product, starmap

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

This generalizes nicely to the setting with more than one ip adress, or more than two variables.



回答5:

How about this?

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

This is three lines of code instead of one --- it's three lines of clear and obvious code instead of importing some special-case helper from module such-and-such. This argument is probably a matter of taste, but it has a lot of weight depending on who you talk to.