带* args的lambda表达式

时间:2014-11-13 02:12:36

标签: python python-3.x lambda tuples args

我知道当我们使用*args时,这意味着我们不确定该函数将接收多少个参数。但是,Python最终将它们绑定在一个元组中:

>>> def f(*args):
    return type(args)

>>> f(3,4,4,5)
<class 'tuple'>

假设我有一个简单的函数,它返回输入不变。我可以使用嵌套的lambda,如下所示:

>>> def f (x):
    return x

>>> l = f(lambda x: len(x))
>>> 
>>> l((1,2,3))
3

请注意,输入是一个元组。但是,当我尝试使用args编写相同的函数时会发生这种情况:

>>> def f (*args):
    return args

>>> l = f(lambda x: len(x))
>>> l((1,2,3))
Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    l((1,2,3))
TypeError: 'tuple' object is not callable

为什么我会收到此错误,我该如何避免?

1 个答案:

答案 0 :(得分:5)

在第二个示例中,l未分配给您认为的内容:

>>> def f (*args):
...     return args
...
>>> l = f(lambda x: len(x))
>>> l
(<function <lambda> at 0x020518A0>,)
>>>

如您所见,包含 lambda函数是一个元组。这是预期的,因为*args总是将其参数收集到元组中,然后函数f返回。

稍后,当你这样做时:

l((1,2,3))

引发TypeError尝试将元组l作为函数调用。


您可以通过简单地索引元组来提取lambda函数来避免此错误:

l = f(lambda x: len(x))[0]

现在l指的是它应该:

>>> def f (*args):
...     return args
...
>>> l = f(lambda x: len(x))[0]
>>> l
<function <lambda> at 0x020169C0>
>>> l((1,2,3))
3
>>>

虽然正如@abarnert在his comment中所说的那样,看起来你实际上是想让l获取可变数量的参数。如果是,那么您需要在 lambda 上使用*args,而不是函数f

>>> def f(x):
...     return x
...
>>> l = f(lambda *args: len(args))
>>> l(1, 2, 3, 4, 5)
5
>>>

请记住,当你执行l(...)时,它就是被调用的lambda。因此,您提供给l的任何参数都将发送到那里。