如何将 lambda 从 python2 迁移到 python3 并处理 python3 中删除的元组参数解包

How to migrate lambda from python2 to python3 and handle removed tuple parameter unpacking in python3

我目前使用的是 python 3.5 和 Ubuntu 16.04。我在 python 2 中有一个代码,我想将它用于 python 3.5。代码由 lambda 组成,传递给它的参数(比方说苹果)由 3 个元组组成。第一个元组是一个数组,看起来像这样:

array([[0,0,0,0],[0,0,0,0]],dtype=uint8)  

第二个元组由一对数字组成,如下所示:

(34,678)  

第三个元组是一个字符串,它由指向特定文件的路径组成:

'/home/king/abcd.png'  

因此我的论点苹果看起来像这样:

apple=(array([[0,0,0,0],[0,0,0,0]],dtype=uint8),(34,678),'/home/king/abcd.png')

现在我知道 python3 中 lambda 的语法发生了变化,同时删除了元组参数解包:

lambda(x, y) : x*x , y*y (python2)  
lambda x_y : x_y[0] * x_y[0] , x_y[1] * x_y[1] (python3)  

现在我的主要 question/problem 是我想访问 lambda 中第一个元组的第一行,即访问:

[[0,0,0,0],[0,0,0,0]]  

传给lambda的参数就是我们的参数apple。 我当前的语法是:

lambda(x,y,z) : x[0] , y , z  (pyhton2)  

lambda x_y_z : ? , ? , ?  (python3)

注意:我不是using/trying/thinking使用python3.8

直接的方法是索引元组:

lambda x_y_z: (x_y_z[0][0], x_y_z[1], x_y_z[2])

您可以在解包可索引序列参数(如元组或列表)的任何情况下机械地应用此方法。我认为这有点丑陋,但在进行更彻底的重构之前,作为让您的测试通过 Python 3 的第一步很好。

如果您仍然要手动升级,则可以嵌套 lambda 来模拟参数解包:

lambda x_y_z: (lambda x, y, z: x[0], y, z)(*x_y_z)

这是否比直接方法的可读性更高或更低,这是值得商榷的。我发现名称比数字更容易阅读,但代价是表达式更复杂。您可能不应该总是以这种方式升级 lambda,因为嵌套参数元组需要太多 lambda 才能解包。但是这种方法也可以解压不能直接索引的迭代器。

请注意,您仍然可以像以前一样通过提前使用 def 和赋值语句来解包,这可能是最易读的:

def spam(x_y_z):
    x, y, z = x_y_z
    return x[0], y, z

这种方法也适用于迭代器参数和嵌套元组。但是你每次都必须想出一个合适的函数名。


can you explain me the meaning of *x_y_z ?

在该上下文中(在调用内),* 将可迭代对象的 contents 作为位置参数传递,而不是可迭代对象本身。也许一个例子会有所帮助:

>>> def show_args(*args):
...     print(args)
...
>>> show_args([1,2,3], 'abc')
([1, 2, 3], 'abc')
>>> show_args(*[1,2,3], *'abc')
(1, 2, 3, 'a', 'b', 'c')