为何DFS函数需用list(path)添加路径?外部无法获正确结果解析
为什么DFS中必须用
res.append(list(path))而不能直接res.append(path)? 我编写了一个DFS函数,用于返回从起点到终点的所有可行路径。但发现函数内部能得到正确路径,外部却无法获取正确结果。代码如下:
res = [] class Solution: def find_all_path(self, graph: list[list]): def dfs(curNode, path: list) -> list[list]: if curNode == target: # 正确写法: # res.append(list(path)) # 错误写法: res.append(path) return # 其他未修改res列表的代码 path = [start_point] dfs(start_point, path) return res
我此前采用类似写法都正常,本次却出现问题,想了解为何必须使用res.append(list(path)),而直接res.append(path)无法得到正确结果?
核心原因:Python列表是可变对象,传递的是引用
- 当你执行
res.append(path)时,只是把path列表的内存引用添加到了res中。整个DFS回溯过程中,path会被反复修改(比如添加节点、回溯时弹出节点),而res里保存的所有元素都是指向同一个path的引用。最终所有路径都会变成path最后一次修改后的状态,导致结果完全错误。 - 而
res.append(list(path))会创建一个path的浅拷贝(新列表),把这个新列表的引用存入res。后续对原path的任何修改都不会影响已经存入res的新列表,这样每个路径都能保留当时的正确状态。
举个极简例子验证这个逻辑:
res = [] path = [1] res.append(path) path.append(2) print(res) # 输出 [[1,2]],而非预期的[[1]]
这就是因为res里存的是path的引用,path的内容变了,res里的内容也跟着同步变化。
为何之前类似写法正常?
可能是以下情况之一:
- 之前的代码中,path是每次递归时重新创建的新列表,而非复用同一个列表做回溯;
- 后续没有对path进行修改操作,或者修改的逻辑不会影响已存入res的引用;
- 之前的场景中,path的生命周期较短,修改时已经不会影响到res里的元素。
内容的提问来源于stack exchange,提问作者W.Nathaniel
相关产品推荐
相关产品推荐

