Lambda参数解包错误

13

在 Python 2 中,这段代码是可以运行的:

f = lambda (m, k): m + k

m = [1,2,3,4]
k = [5,6,7,8]

print(map(f, zip(m, k)))

但是在Python 3中,出现了以下错误:

f = lambda (m, k): m + k
^
SyntaxError: invalid syntax

如果我在lambda表达式中删除括号,那么会出现另一个错误:

TypeError: <lambda>() missing 1 required positional argument: 'k'

在Python 3中,将元组作为单个lambda参数进行处理也可以,但这不太清晰(阅读起来困难):

f = lambda args: args[0] + args[1]

我该如何在Python 3中以正确的方式解压值?


map()函数将函数f应用于提供的可迭代对象中的每个元素;在您给出的示例中,map()尝试将(1, 5)传递给您的函数,该函数需要两个参数,但只提供了一个参数,因此失败并给出错误提示。 - dazedconfused
他们将它从函数中移除,以便与类型提示(等等)更好地协作。此外,请参阅我的答案:https://dev59.com/ZaDia4cB1Zd3GeqPIb3S#54991720 - Tomasz Gandor
6个回答

14

元组解包的移除在PEP 3113中被讨论。基本上,在Python 3中您无法这样做。在标题过渡计划下,您将看到“建议”的做法是将其作为您的最终代码块:

lambda x_y: x_y[0] + x_y[1]

9

如果您使用itertools.starmap而不是map,则可以在Python 2和Python 3中使用相同的语法,因为它会自动为我们解包元组项:

>>> from itertools import starmap
>>> f = lambda m, k: m + k
>>> list(starmap(f, zip(m, k)))
[6, 8, 10, 12]

7
您可能会发现这个解决方案更易于阅读:
lambda mk: (lambda m,k: m + k)(*mk)

此外,我认为这种解包方式使得代码更符合 Python 风格并且更加符合 命名 函数元组参数的手动解包规范,这也是 Python 3 中由 PEP 3113 所要求的。

2
非常好,尽管有点复杂(顺便问一句,这是“pythonic”的同义词吗?)。对于超过2个元素的元组,这种方法绝对会胜出!索引真的很糟糕。想想:lambda abcdef: abcdef[0] + abcdef[2] - abcdef[1] // abcdef[4] - Tomasz Gandor

4

在Python3中,无法在lambda函数中使用括号来解包参数(PEP 3113),请尝试:

f = lambda m, k: m + k

要让它与您的代码配合使用,您应该使用:

lambda mk: mk[0] + mk[1]

它能够与map(f, zip(m, k))一起工作吗?至于(我写的),出现了TypeError。 - mblw
@Alexei 那你应该尝试 lambda mk: mk[0] + mk[1]。在我回答之前我没有看过你的代码的其余部分 :) - Maroun
感谢您的关注。我认为这是Python演进中的一些奇怪决定... - mblw

1

或者您可以直接使用sum()函数来对数字进行求和,无需拆包:

f = lambda args: sum(args)

谢谢你的回答 =)但那只是一个简单的例子。实际上我的lambda函数更加复杂。而且我认为只需要使用sum函数,不用套在lambda里面。 - mblw

1

只需使用

map(f, m, k)

请注意,f 可以是。
from operator import add
map(add, m, k)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接