Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在递归问题中,为什么要在python列表上使用list()方法?_Python_Python 3.x_Recursion - Fatal编程技术网

在递归问题中,为什么要在python列表上使用list()方法?

在递归问题中,为什么要在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):

我目前正在学习Python中的深度优先搜索,有一个问题是,给定一个二叉搜索树和一个数字N,查找从根到叶的所有路径,使每个路径的所有节点值之和等于N

我做的每件事都是对的,但是我的代码不起作用(它导致了一个空的2D数组)。在查看解决方案时,唯一的区别是“allPath.append(list(currPath))”,而我编写的代码只是“allPath.append(currPath)”。当我进行此更改时,代码运行良好完整的代码如下:

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()
也会生成列表的浅层副本,如果您不希望对一个列表进行更改以影响之前附加的所有列表,这一点很重要,对于这样的递归问题,这种方法可以避免共享对象/列表的突变。。我发现递归(和代码一样多)通常更容易推理,没有不必要的副作用