在递归问题中,为什么要在python列表上使用list()方法?
我目前正在学习Python中的深度优先搜索,有一个问题是,给定一个二叉搜索树和一个数字N,查找从根到叶的所有路径,使每个路径的所有节点值之和等于N 我做的每件事都是对的,但是我的代码不起作用(它导致了一个空的2D数组)。在查看解决方案时,唯一的区别是“allPath.append(list(currPath))”,而我编写的代码只是“allPath.append(currPath)”。当我进行此更改时,代码运行良好完整的代码如下:在递归问题中,为什么要在python列表上使用list()方法?,python,python-3.x,recursion,Python,Python 3.x,Recursion,我目前正在学习Python中的深度优先搜索,有一个问题是,给定一个二叉搜索树和一个数字N,查找从根到叶的所有路径,使每个路径的所有节点值之和等于N 我做的每件事都是对的,但是我的代码不起作用(它导致了一个空的2D数组)。在查看解决方案时,唯一的区别是“allPath.append(list(currPath))”,而我编写的代码只是“allPath.append(currPath)”。当我进行此更改时,代码运行良好完整的代码如下: def findPathSum(root, sum):
def findPathSum(root, sum):
allPath = []
_findPathSum(root, sum, [], allPath)
return allPath
def _findPathSum(currNode, sum, currPath, allPath):
if currNode is None:
return
currPath.append(currNode.val)
if currNode.val == sum and currNode.left is None and currNode.right is None:
print(currPath)
allPath.append(list(currPath))
else:
_findPathSum(currNode.left, sum-currNode.val, currPath, allPath)
_findPathSum(currNode.right, sum-currNode.val, currPath, allPath)
del currPath[-1]
我感到困惑的是currPath已经是一个列表,并且只包含整数(即节点值)。在将currPath附加到AllPath之前打印currPath时,它也会正确显示一个包含整数值的列表。然而,在我将其附加到AllPath之后,AllPath只是一个空数组。但是,出于某种原因,使用list()方法显示具有正确整数值的正确二维数组。我不知道为什么会这样
根据我的理解,list()方法只需获取一个iterable并将其转换为一个list……然而currPath已经是一个list了。我觉得我错过了一些非常明显的东西。
list
创建了一个全新的列表(虽然元素不是全新的),一个新的列表对象。在您的情况下,如果不使用list
,您只需在每次递归调用中将完全相同的list对象附加到allPath
因此,由于
allPath
的所有元素都是完全相同的列表,因此更改该列表会更改allPath
的所有元素。例如,当在\u findPathSum
的末尾执行del currPath[-1]
时,实际上是在删除allPath
中每个元素的最后一个元素。由于最后的currPath
将是空的,这就是您在allPath
中看到的,一个包含空列表的列表。list
创建一个全新的列表(尽管元素不是全新的),一个新的列表对象。在您的情况下,如果不使用list
,您只需在每次递归调用中将完全相同的list对象附加到allPath
因此,由于
allPath
的所有元素都是完全相同的列表,因此更改该列表会更改allPath
的所有元素。例如,当在\u findPathSum
的末尾执行del currPath[-1]
时,实际上是在删除allPath
中每个元素的最后一个元素。由于最后的currPath
将是空的,这就是您在allPath
中最后看到的内容-一个包含空列表的列表。list()
也会创建列表的浅层副本,如果您不希望更改一个列表以影响之前添加的所有列表,这一点很重要。尽管,对于这样的递归问题,这种方法可以避免共享对象/列表的突变。。我发现递归(和代码一样多)通常更容易推理,不会产生不必要的副作用。请注意,list
是一个类而不是一个方法list()
也会生成列表的浅层副本,如果您不希望对一个列表进行更改以影响之前附加的所有列表,这一点很重要,对于这样的递归问题,这种方法可以避免共享对象/列表的突变。。我发现递归(和代码一样多)通常更容易推理,没有不必要的副作用