Python 2和Python 3中的Lambda地图行为

时间:2018-09-03 15:13:30

标签: python lambda

我在查看别人对LeetCode的解决方案时遇到了一些代码:

def findLeaves(self, root):
    if not root: return []
    kids = map(self.findLeaves, (root.left, root.right))
    return map(lambda l, r: (l or []) + (r or []), *kids) + [[root.val]]

我发现它仅适用于Python 2,而不适用于3,因此我进行了以下调试:

Python 2:

a = [[],[]]
b = map(lambda l, r: (l or []) + (r or []), *a) + [[4]]
c = map(lambda l, r: (l or []) + (r or []), *a) + [[5]]
d = map(lambda l, r: (l or []) + (r or []), *[b,c]) + [[2]]
e = [[3]]
f = map(lambda l, r: (l or []) + (r or []), *[d,e]) + [[1]]
print f

Python 3:

a = [[],[]]
b = list(map(lambda l, r: (l or []) + (r or []), *a)) + [[4]]
c = list(map(lambda l, r: (l or []) + (r or []), *a)) + [[5]]
d = list(map(lambda l, r: (l or []) + (r or []), *[b,c])) + [[2]]
e = [[3]]
f = list(map(lambda l, r: (l or []) + (r or []), *[d,e])) + [[1]]
print(f)

上面的代码在Python 2中返回[[4, 5, 3], [2], [1]](正确),在Python 3中返回[[4, 5, 3], [1]](错误)。

*[d,e][[4,5], [2]] [[3]],在Python 2中,当处理[[2]]时,它将在lambda表达式中自动将None分配给r。但是在Python 3中,它将跳过记录。

我还发现,在Python 2中,如果将f更改为list(map(lambda l, r: (l or []) + (r or []), *itertools.zip_longest(d,e))) + [[1]],它将起作用。但是,这将弄乱b和c的情况。

谁能解释修复代码的正确方法是什么?此外,我的调试方式非常笨拙(我总是使用打印),还有更好的调试代码方式吗?我是Python的新手,并使用Jupyter笔记本运行代码。

1 个答案:

答案 0 :(得分:2)

python 3中的

map不能用None填充,您需要自己做。您可能要使用zip_longest甚至是星图。

Python 2 docs for map

  

map(function,iterable,...)将函数应用于所有可迭代项   并返回结果列表。如果还有其他可迭代参数   通过后,函数必须接受那么多参数并将其应用于   来自所有可迭代对象的项目。如果一个迭代小于   另一个假定扩展为无项目。如果函数是   无,假定身份函数;如果有多个   参数,map()返回一个包含元组的列表,其中元组包含   所有可迭代项的对应项(一种转置   操作)。可迭代参数可以是序列或任何可迭代   宾语;结果总是一个列表。

Python 3 docs for map

  

返回将函数应用于所有可迭代项的迭代器,   产生结果。如果传递了其他可迭代的参数,   函数必须接受那么多参数,并应用于项目   来自所有可迭代对象的并行操作。有了多个可迭代项,迭代器   当最短的迭代次数用尽时停止。对于以下情况   函数输入已经安排到参数元组中,请参见   itertools.starmap()。