带*args的lambda表达式

Omi*_*mid 2 python lambda tuples args python-3.x

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

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

>>> f(3,4,4,5)
<class 'tuple'>
Run Code Online (Sandbox Code Playgroud)

假设我有一个简单的函数,它返回输入不变.我可以像这样使用嵌套的lambda:

>>> def f (x):
    return x

>>> l = f(lambda x: len(x))
>>> 
>>> l((1,2,3))
3
Run Code Online (Sandbox Code Playgroud)

请注意,输入是一个元组.但是,当我尝试使用以下函数编写相同的函数时会发生这种情况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
Run Code Online (Sandbox Code Playgroud)

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

iCo*_*dez 5

在第二个示例中,l未分配给您的想法:

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

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

以后,当你这样做时:

l((1,2,3))
Run Code Online (Sandbox Code Playgroud)

a TypeError是为了尝试将元组l作为函数调用而引发的.


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

l = f(lambda x: len(x))[0]
Run Code Online (Sandbox Code Playgroud)

现在l指的是它应该:

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

虽然,正如@abarnert在他的评论中所说的那样,看起来你实际上是在尝试l采取不同数量的论点.如果是这样,那么你需要*argslambda上使用,而不是函数f:

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

请记住,当你这样做时l(...),它就是被调用的lambda.所以,你给的任何论据l都会被发送到那里.