使用map()函数将非可迭代变量传递给一个函数

10

我是一名Python开发者,正在尝试转换一个具有以下结构的函数:

def func(g,h,iterable):
 return iterable*(g+h)

for iterable in range(20):
  print func(2,3,iterable)

转换为映射函数:

def func(g,h,iterable):
 return iterable*(g+h)

print map(func,2,3,range(20)) #does not work...

我遇到的问题是如何通过map()函数传递常量,目前我不知道该怎么做。
我希望能够使用这种结构,以便轻松使用Ipython并行工具。
假设:
  • 在所有可迭代对象上完成实际函数需要大约1.5小时(因此希望使用并行map()函数)
  • 该函数很复杂,不能使用列表推导式
本质上,如果还不明显,我是一名MATLAB程序员,正在转向Python,并寻找MATLAB中parfor函数的良好替代品。
4个回答

7
一方面,如果你将函数映射到一个range上,那么没有参数是可迭代的。
至于你的问题,你可以使用functools.partial将位置参数(从左到右)绑定到函数。
def func(g,h,i):
    return i*(g+h)

print map(functools.partial(func, 2,3), range(20))

# [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

要绑定任何位置参数,请使用像hkpeprah的回答中所述的lambda表达式。


请注意,partial 不能用于指定任意精度的位置参数。例如,如果您想始终提供第三个参数,则必须使用其关键字,或者您必须使用一个 lambda lambda x,y: func(x,y,const) - Bakuriu
太棒了,Thomas的答案加上Bakuriu的改进完美地解决了我所要做的事情! - Rob andrews

5
如果您提前知道参数,可以使用 lambda 函数,如下所示:
f = lambda lst: func(2,3,lst)
map(f, range(20))

或者,如果您不知道参数,可以使用lambda表达式进行包装

f = lambda x: lambda y: lambda lst: func(x,y,lst)
f = f(2)
f = f(3)
map(f, range(20))

1
你可以使用闭包(closures):
def initFunction(g, h):
    def funct(value):
        return g * h * value
    return funct

myFunct = initFunction(g, h)
mapped = map(myFunct, range(20)) 

PS. 我猜你在使用Python 3.x,否则对于大数值来说,xrange和生成器推导式比range更好!(等效的2.7代码):

def initFunction(g, h):
    def funct(value):
        return g * h * value
    return funct

myFunct = initFunction(g, h)
mapped = (myFunct(i) for i in xrange(20)) 

0

也许不是最优雅的方法,但你可以将gh变成可迭代对象,然后直接将它们传递给map函数:

## the original function: 
def func(g,h,i):
    return i*(g+h)

## define some values
g1 = 2
h1 = 5
iterable1 = list(range(10))

## make g and h iterable
g1_iter = [g1] * len(iterable1)
h1_iter = [h1] * len(iterable1)

print(list(map(func, g1_iter, h1_iter, iterable1)))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接