66

Is there any way to map list items to a function along with arguments?

I have a list:

pages = [p1, p2, p3, p4, p5...]

And I have to call function myFunc corresponding to each list elements along with additional arguments such that the following can be computed

myFunc(p1, additionalArgument)
myFunc(p2, additionalArgument)

and so on...

Is there any elegant method for doing this?

2

4 Answers 4

135

You can also use a lambda function:

map(lambda p: myFunc(p, additionalArgument), pages)
Sign up to request clarification or add additional context in comments.

7 Comments

why is using map(lambda p: myFunc(p, additionalArgument), pages) superior to [myFunc(p, additionalArgument) for p in pages]? I'd suggest that this is only the case for very simple functions. Would gladly accept comments as I am new to python
@OldSchool Most people consider list comprehensions to be more idiomatic in Python than using map(). Guido even wanted to remove map() from the language at some point. However, the community decided to keep it, so it's definitely fine to use if you prefer it. I personally often use it when mapping an existing function over an iterable, but I'd never use map(lambda:..., ...), since this really has no advantage over a list comprehension, and is even slower due to the added function call overhead.
@Sven, thanks. Makes sense. Leaving map() aside, is there any reason to write [lambda p: myFunc(p, additionalArgument) for p in pages] rather than just [myFunc(p,additionalArgument) for p in pages]?
@OldSchool Sure, you can write that if you want a list of lambda functions. Note that these lambda funcitons will just be created and stored in the list. They won't be called by the list comprehension. It is unclear to me what you are trying ot achieve.
@Sven. What I am trying to say is that I don't see the benefit of using the lambda keyword if the lambda is just calling myFunc(). Might as well just put myFunc() in there without wrapping it in a lambda no?
|
85

Use a list comprehension:

result = [myFunc(p, additionalArgument) for p in pages]

7 Comments

Once read, obviously elegant (with the side effect to never use map() again...)
@AdN: map has its uses. map(f, lst) is less repetitive than [f(x) for x in lst].
Why not a simple loop? Seriously? Why complicate things? for p in pages: myFunc(p, additionalArgument)
@AFP_555 speed. A for loop is several orders of magnitude slower than mapping. This matters when you're working with millions of objects.
@JosephFarah No, the for loop isn't slower, and certainly not by several orders of magnitude. Why would it be? If you need a list of the results of the function calls, use the list comprehension. If you just want to call the functions, use a for loop.
|
53

You could use a list comprehension

[myFunc(p, additionalArgument) for p in pages]

or functools.partial()

map(functools.partial(myFunc, some_arg=additionalArgument), pages)

2 Comments

This should be the accepted answer. A list comprehension is more simple while the map() function is more faster. The functools.partial() method should be used when there's speed requirement. And this version can be also useful to multiprocessing.pool.map().
@C.K.I don't expect map(partial(...), ...) to be faster than a list comprehension, except maybe in a few corner cases. I just added it for completeness and use cases like pool.map(). I think the accepted answer is perfectly fine, since the list comprehension is generally considered the most idiomatic solution for this use case. What's beyond me is how on earth the map(lambda: ..., ...) answer added years later got voted so highly – it's slower, less succinct and less readable than the list comprehension.
3

Note that if you're planning to use map for distributed computations (i.e. using multiprocessing) it will not unpack the arguments as one could expect. Say you want to distribute your call to myFunc (which accepts two arguments: page and additionalArgument) with:

pages = [p1, p2, p3, p4, p5...]

If you specify a list of args (tuples), i.e.

args = [(page, additionalArgument) for page in pages]

map will not unpack the args tuple and will pass only one argument (tuple) to myFunc:

pool.map(myFunc, args)  # map does not unpack the tuple

You will need to use multiprocessing.starmap instead

starmap is like map() except that the elements of the iterable are expected to be iterables that are unpacked as arguments.

i.e.

pool.starmap(myFunc, args)  # tuples are unpacked and two arguments are passed to myFunc

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.