如何将 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')
我目前使用的是 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')