更改函数列表(lambda)时出现意外结果



我有一个函数列表,每个函数都有一个参数。

我想使用库中的函数,该函数接受函数,但希望它们没有参数。

因此,我想使用lambda来创建一个新函数列表;外部";

但是,新的函数列表没有产生预期的结果

(这是一个最小的例子(

def fun_a(param):
print("a")

def fun_b(param):
print("b")

def do_something(funs):
funs_out = []
for fun in funs:
funs_out.append(lambda: fun(0))

return funs_out


funs = [fun_a,fun_b]
funs[0](0) # prints a
funs[1](0) # prints b
funs_changed = do_something(funs)
#funs_changed = [lambda: f(0) for f in funs]

funs_changed[0]() # prints b ??? expected a
funs_changed[1]() # prints b

我以前尝试过funs_changed = [lambda: f(0) for f in funs],因为它看起来更像蟒蛇,然后尝试使用更明确的代码(raw for loop(来找到根本原因,但没有成功。

我想念什么?

您可以使用functools.partial:

from functools import partial

def fun_a(param):
print("a")

def fun_b(param):
print("b")

def do_something(funs):
funs_out = []
for fun in funs:
funs_out.append(partial(fun, 0))

return funs_out


funs = [fun_a, fun_b]
funs[0](0)   # prints a
funs[1](0)   # prints b
funs_changed = do_something(funs)
# funs_changed = [partial(fun, 0) for f in funs]

funs_changed[0]() # prints a
funs_changed[1]() # prints b

根据这个答案:

大致上,partial做的事情是这样的(除了关键字args支持等(:

def partial(func, *part_args):
def wrapper(*extra_args):
args = list(part_args)
args.extend(extra_args)
return func(*args)
return wrapper

只需使用值破解:

funs_changed = [lambda f=f: f(0) for f in funs]

它将是可以的,并产生一个输出:

a
b
a
b

此外,还有一个针对代码初始变体的解决方案:如果您喜欢将do_something函数保留为函数,则只需对其进行修补,以避免在主代码上下文中进行内联lamda列表压缩(我们将在函数中进行(:

def do_something(funs):
funs_out = [lambda f=f: f(0) for f in funs]
return funs_out

相关内容

  • 没有找到相关文章

最新更新