问题:如何做多个参数来映射函数在python中保持不变?
可以说我们有一个函数添加如下
def add(x, y):
return x + y
我们要对数组应用map函数
map(add, [1, 2, 3], 2)
语义是我想将2添加到数组的每个元素。但是该map
函数也需要第三个参数中的列表。
注意:为了简单起见,我将添加示例。我原来的功能要复杂得多。当然,设置y
in add函数默认值的选项是毫无疑问的,因为每次调用都会更改它。
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.
回答 0
一种选择是列表理解:
[add(x, 2) for x in [1, 2, 3]]
更多的选择:
a = [1, 2, 3]
import functools
map(functools.partial(add, y=2), a)
import itertools
map(add, a, itertools.repeat(2, len(a)))
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)))
回答 1
文档明确建议这是以下用途的主要用途itertools.repeat
:
制作一个迭代器,一次又一次返回对象。除非指定了times参数,否则将无限期运行。用作map()
被调用函数的不变参数的参数。还用于zip()
创建元组记录的不变部分。
而且没有理由将通过len([1,2,3])
作为times
论点。map
第一个可迭代项被消耗后立即停止,因此无限可迭代性就很好了:
>>> from operator import add
>>> from itertools import repeat
>>> list(map(add, [1,2,3], repeat(4)))
[5, 6, 7]
实际上,这等效repeat
于docs中的示例:
>>> list(map(pow, range(10), repeat(2)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
这提供了一个不错的惰性函数式语言y解决方案,该解决方案也可以用Python迭代器术语完美地读取。
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.
回答 2
使用列表理解。
[x + 2 for x in [1, 2, 3]]
如果你真的,真的,真的想用map
,给它一个匿名函数作为第一个参数:
map(lambda x: x + 2, [1,2,3])
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])
回答 3
Map可以包含多个参数,标准方式是
map(add, a, b)
您的问题应该是
map(add, a, [2]*len(a))
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))
回答 4
正确的答案比您想像的要简单。只需做:
map(add, [(x, 2) for x in [1,2,3]])
并改变添加实现的元组即
def add(t):
x, y = t
return x+y
这可以处理两个添加参数都是动态的任何复杂用例。
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.
回答 5
有时我使用闭包解决了类似的情况(例如使用pandas.apply方法)
为了使用它们,您需要定义一个函数,该函数可以动态定义并返回该函数的包装器,从而有效地使参数之一成为常数。
像这样:
def add(x, y):
return x + y
def add_constant(y):
def f(x):
return add(x, y)
return f
然后,add_constant(y)
返回一个可用于添加y
到任何给定值的函数:
>>> add_constant(2)(3)
5
这样,您就可以在一次给定一个参数的任何情况下使用它:
>>> map(add_constant(2), [1,2,3])
[3, 4, 5]
编辑
如果您不想在其他地方编写闭包函数,则始终可以使用lambda函数即时构建它:
>>> map(lambda x: add(x, 2), [1, 2, 3])
[3, 4, 5]
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]
回答 6
如果可用,我将考虑使用numpy。这些类型的操作非常快:
>>> import numpy
>>> numpy.array([1,2,3]) + 2
array([3, 4, 5])
这是假设您的实际应用程序正在做数学运算(可以向量化)。
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).
回答 7
如果确实需要使用map函数(例如此处的类分配…),则可以使用具有1个参数的包装器函数,将其余函数传递给其主体中的原始函数;即:
extraArguments = value
def myFunc(arg):
# call the target function
return Func(arg, extraArguments)
map(myFunc, itterable)
肮脏和丑陋,仍然可以解决问题
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
回答 8
我相信星图是您所需要的:
from itertools import starmap
def test(x, y, z):
return x + y + z
list(starmap(test, [(1, 2, 3), (4, 5, 6)]))
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)]))
回答 9
将多个参数传递给一个map
函数。
def q(x,y):
return x*y
print map (q,range(0,10),range(10,20))
这里q是一个多说法,函数映射()的调用。确保两个范围的长度,即
len (range(a,a')) and len (range(b,b')) are equal.
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.
回答 10
在:nums = [1, 2, 3]
在:map(add, nums, [2]*len(nums))
出:[3, 4, 5]
In :nums = [1, 2, 3]
In :map(add, nums, [2]*len(nums))
Out:[3, 4, 5]
回答 11
您可以在地图中包含lambda:
list(map(lambda a: a+2, [1, 2, 3]))
You can include lambda along with map:
list(map(lambda a: a+2, [1, 2, 3]))
回答 12
def func(a, b, c, d):
return a + b * c % d
map(lambda x: func(*x), [[1,2,3,4], [5,6,7,8]])
通过使用lambda包装函数调用并使用星号拆包,您可以使用任意数量的参数进行映射。
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.
回答 13
另一个选择是:
results = []
for x in [1,2,3]:
z = add(x,2)
...
results += [f(z,x,y)]
调用多个函数时,此格式非常有用。
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.