对python中的lambda表达式感到困惑吗

对python中的lambda表达式感到困惑吗,python,lambda,Python,Lambda,我理解正常的lambda表达式,例如 g = lambda x: x**2 然而,对于一些复杂的问题,我有点困惑。例如: for split in ['train', 'test']: sets = (lambda split=split: newspaper(split, newspaper_devkit_path)) def get_imdb(): return sets() 其中,报纸是一个函数。我想知道sets实际上是什么,为什么get\u imdb函数可以返回值s

我理解正常的lambda表达式,例如

g = lambda x: x**2
然而,对于一些复杂的问题,我有点困惑。例如:

for split in ['train', 'test']:
    sets = (lambda split=split: newspaper(split, newspaper_devkit_path))

def get_imdb():
    return sets()
其中,
报纸
是一个函数。我想知道
sets
实际上是什么,为什么
get\u imdb
函数可以返回值
sets()

谢谢你的帮助

增加: 代码实际上是从这里来的

一个lambda函数:

func = lambda x: x**2
可以几乎等价地重写:

def func(x):
    return x**2
无论使用哪种方法,都可以通过以下方式调用函数:

func(4)

以你为例,

sets = lambda split=split: newspaper(split, newspaper_devkit_path)
可以重写:

def sets(split=split):
    return newspaper(split, newspaper_devkit_path)
因此可以称之为:

sets()

当您编写以下内容时:

def get_imdb():
    return sets()

您正在定义一个“闭包”。对函数
set
的引用保存在
get\u imdb
中,以便以后在调用
get\u imdb
的任何地方都可以调用该函数。

可能您对
split=split
部分感到困惑。这与在常规函数中的含义相同:左侧的拆分是lambda函数的参数,右侧的拆分是没有提供值时左侧拆分采用的默认值。在这种情况下,默认值将是for循环中定义的变量
split

那么,回答您的第一个问题(什么是
集合
?):

集合
是一个分配了匿名函数(或lambda函数)的变量。这允许通过变量
set
引用和使用lambda函数

关于你的第二个问题(为什么可以返回
set()
呢?),我回答:


由于
集合
是一个充当函数的变量,因此在调用lambda函数后添加括号。因为没有给出任何参数,所以参数
split
采用值
'test'
,这是循环变量
split
采用的最后一个值。这里值得注意的是,由于函数
get\u imdb
中未定义
set
,因此解释器在
get\u imdb
范围外查找
set
的定义(并找到引用lambda函数的定义).

设置
被分配一个lambda,该lambda实际上不应该接受输入,从调用它的方式可以看出。lambda的行为通常类似于正常函数,因此可以分配给变量,如
g
集合
集合
的定义被一组额外的括号包围,没有明显的原因。你可以忽略那些外部参数

Lambdas可以具有与普通函数相同的所有类型的位置参数、关键字参数和默认参数。lambda
集合
有一个名为
split
的默认参数。这是一个常见的习惯用法,用于确保循环的每个迭代中的
集合
都获得对应于该迭代的
split
值,而不是在所有情况下仅获得上一次迭代的值

如果没有默认参数,
split
将在lambda中根据调用时的名称空间进行计算。一旦循环完成,外部函数名称空间中的
split
将只是它对循环的最后一个值

创建函数对象时,会立即计算默认参数。这意味着默认参数
split
的值将位于创建它的循环的迭代中的任何位置

您的示例有点误导,因为它丢弃了
集合
中除最后一个之外的所有实际值,使得lambda的默认参数没有意义。下面是一个示例,说明如果保留所有lambda会发生什么。首先使用默认参数:

sets = [] for split in ['train', 'test']: sets.append(lambda split=split: split) print([fn() for fn in sets])
这是因为
'test'
是计算所有lambda时的
split
值。

您确定代码正确吗?每次迭代都不断地重新分配
集合
真的很奇怪。我认为这只是OP试图创建一个最小的示例。根据问题本身,此代码不是他自己的。您没有说明默认参数的用途,也没有说明
设置的所有值都被丢弃了,但最后一个值被丢弃了
def get_imb():…
不创建闭包。当我们调用
fn
时,会不会没有参数?以
g=lambda x:x**2
为例,我们需要将其称为
g(2)
,而
g()
没有意义。如果它有默认参数,那么它看起来还可以,因为在创建它时已经生成了值。但是对于没有默认参数的,我们是否应该在最后一个示例中使用
print([fn(split)表示集合中的fn])
?在最后一个示例中,lambda函数定义为
lambda:split
,即。E它是一个类似于
def func():
(一个没有参数的函数)。如果lambda函数使用参数,则必须将其定义为e。G作为
lambda x:x**2
(您的第一个可理解的示例)-参数名介于
lambda
之间:
。 sets = [] for split in ['train', 'test']: sets.append(lambda: split) print([fn() for fn in sets])