在python中初始化lambda函数列表

2024-09-27 09:26:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个函数元组,我想用一些数据预加载。目前我这样做的方式如下。本质上,我列出了一个新函数的列表,每次添加一个lambda函数,然后重新转换为一个元组。但是,当我在代码的不同部分使用这些函数时,它们中的每一个都会像是列表中的最后一个。在

def newfuncs(data, funcs):
    newfuncs = []
    for f in funcs:
        newf = lambda x: f(x, data)
        newfuncs.append(newf)
    return tuple(newfuncs)

下面是这个问题的一个简单例子

^{pr2}$

我希望数字15打印出来,然后是-5。但是,这段代码将数字-5打印两次。如果有人能帮助我理解为什么会发生这种事,我将不胜感激。谢谢!在


Tags: 数据lambda函数代码列表fordatadef
2条回答

如前所述,问题在于变量f,它是分配给所有lambda函数的同一个变量,因此在循环的末尾,每个lambda看到的是相同的f。在

这里的解决方案是使用functools.partial,或者为lambda创建一个限定范围的默认参数:

def newfuncs(data, funcs):
    newfuncs = []
    for f in funcs:
        newf = lambda x, f=f: f(x, data)   # note the f=f bit here
        newfuncs.append(newf)
    return tuple(newfuncs) 

像以前一样调用这些lambda现在可以得到:

^{pr2}$

如果您使用的是python3.x,请确保将此comment by ShadowRanger作为作用域默认参数方法的一个可能的安全特性。

这是一个众所周知的Python“问题”,或者我应该说“Python就是这样的”

您创建了元组:

( x => f(x, data), x => f(x, data) )

但是f是什么?f在您最后调用函数之前不会求值!在

首先,f是{}。然后在for-循环中,f被重新分配给(x, y)=>x-y。在

当您终于开始调用函数时,那么,而且只有这样,才会查找f的值。此时f的值是多少?所有函数的值都是(x, y)=>x-y。你所有的函数都做减法。这是因为f被重新分配。只有一个f。在调用任何lambda之前,将该函数的值设置为减法函数。在

附录

如果有人感兴趣,不同的语言以不同的方式处理这个问题。JavaScript在这里很有意思(有些人会说它令人困惑),因为它以Python的方式进行操作,这是OP意外的,而且是OP所期望的另一种方式。在JavaScript中:

^{pr2}$

但是,如果您将上面的let更改为var,它的行为类似于Python,并且两者都得到-5!这是因为使用let,for循环的每次迭代都会得到不同的f;使用var,整个函数共享相同的f,它会不断被重新分配。这就是Python的工作原理。在

cᴏʟᴅsᴘᴇᴅ已经向您展示了实现您期望的方法是确保每次迭代都得到不同的f,Python允许您以非常简洁的方式来做,将lambda的第二个参数默认为该迭代的本地f。这很酷,所以如果他们的回答对你有帮助的话,你应该接受。在

相关问题 更多 >

    热门问题