# How to do multiple arguments to map function where one remains the same

## Question:

Let’s say we have a function `add`

as follows

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

we want to apply map function for an array

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

The semantics are I want to add 2 to every element of the array. But the `map`

function requires a list in the third argument as well.

**Note:** I am putting the `add`

example for simplicity. My original function is much more complicated. And of course option of setting the default value of `y`

in `add`

function is out of question as it will be changed for every call.

## Answers:

Use a list comprehension.

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

If you *really*, *really*, *really* want to use `map`

, give it an anonymous function as the first argument:

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

One option is a list comprehension:

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

More options:

```
a = [1, 2, 3]
import functools
map(functools.partial(add, y=2), a)
import itertools
map(add, a, itertools.repeat(2, len(a)))
```

If you have it available, I would consider using numpy. It’s very fast for these types of operations:

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

This is assuming your real application is doing mathematical operations (that can be vectorized).

If you really really need to use map function (like my class assignment here…), you could use a wrapper function with 1 argument, passing the rest to the original one in its body; i.e. :

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

Dirty & ugly, still does the trick

The docs explicitly suggest this is the main use for `itertools.repeat`

:

Make an iterator that returns object over and over again. Runs indefinitely unless the times argument is specified. Used as argument to

`map()`

for invariant parameters to the called function. Also used with`zip()`

to create an invariant part of a tuple record.

And there’s no reason for pass `len([1,2,3])`

as the `times`

argument; `map`

stops as soon as the first iterable is consumed, so an infinite iterable is perfectly fine:

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

In fact, this is equivalent to the example for `repeat`

in the docs:

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

This makes for a nice lazy-functional-language-y solution that’s also perfectly readable in Python-iterator terms.

Another option is:

```
results = []
for x in [1,2,3]:
z = add(x,2)
...
results += [f(z,x,y)]
```

This format is very useful when calling multiple functions.

Sometimes I resolved similar situations (such as using pandas.apply method) using closures

In order to use them, you define a function which dynamically defines and returns a wrapper for your function, effectively making one of the parameters a constant.

Something like this:

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

Then, `add_constant(y)`

returns a function which can be used to add `y`

to any given value:

```
>>> add_constant(2)(3)
5
```

Which allows you to use it in any situation where parameters are given one at a time:

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

**edit**

If you do not want to have to write the closure function somewhere else, you always have the possibility to build it on the fly using a lambda function:

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

To pass multiple arguments to a `map`

function.

```
def q(x,y):
return x*y
print map (q,range(0,10),range(10,20))
```

Here **q** is function with multiple argument that **map()** calls.

Make sure, the length of both the ranges i.e.

```
len (range(a,a')) and len (range(b,b')) are equal.
```

Map can contain multiple arguments, the standard way is

```
map(add, a, b)
```

In your question, it should be

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

The correct answer is simpler than you think.

Simply do:

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

And change the implementation of add to take a tuple i.e

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

This can handle any complicated use case where both add parameters are dynamic.

In :`nums = [1, 2, 3]`

In :`map(add, nums, [2]*len(nums))`

Out:`[3, 4, 5]`

```
def func(a, b, c, d):
return a + b * c % d
```

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

By wrapping the function call with a lambda and using the star unpack, you can do map with arbitrary number of arguments.

I believe starmap is what you need:

```
from itertools import starmap
def test(x, y, z):
return x + y + z
list(starmap(test, [(1, 2, 3), (4, 5, 6)]))
```

You can include lambda along with map:

```
list(map(lambda a: a+2, [1, 2, 3]))
```

```
#multi argument
def joke(r):
if len(r)==2:
x, y = r
return x + y
elif len(r)==3:
x,y,z=r
return x+y+z
#using map
print(list(map(joke,[[2,3],[3,4,5]])))
```

output = [6,12]

if the case like above and just want use function

```
def add(x,y):
ar =[]
for xx in x:
ar.append(xx+y)
return ar
print(list(map(add,[[3,2,4]],[2]))[0])
output = [5,4,6]
```

Note: you can modified as you want.