我正在编写一个简单的DFS算法,但是当我运行该函数时,似乎要传递的参数会在下一个调用中继续使用。我对Python范围定义的工作方式感到满意,但是我从来没有真正考虑过范围设定对参数的作用。有人可以解释这个范围界定问题是如何发生的吗?
我能想到的唯一原因是,我每次运行该函数时都不会重新创建默认值。
图形对象:
graph = {
1: [2,8,12],
2: [3,7],
3: [4,5,6],
8: [9],
9: [10,11],
12: [13],
13: [14]
}
DFS算法:
def dfs_dict(graph, curr, val, path=[]):
path.append(curr)
print "Path: " + str(path)
if curr == val:
return path
else:
if curr in graph: # not a disconnected node/leaf
for child in graph[curr]:
if child not in path:
tmp = dfs_dict(graph, child, val, path)
if tmp:
return tmp
我如何运行DFS:
if __name__ == '__main__':
print dfs_dict(graph, 1, 13)
print dfs_dict(graph, 1, 7)
输出:
Path: [1]
Path: [1, 2]
Path: [1, 2, 3]
Path: [1, 2, 3, 4]
Path: [1, 2, 3, 4, 5]
Path: [1, 2, 3, 4, 5, 6]
Path: [1, 2, 3, 4, 5, 6, 7]
Path: [1, 2, 3, 4, 5, 6, 7, 8]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Path: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1]
None
最佳答案
问题是path
的默认值在这里:def dfs_dict(graph, curr, val, path=[]):
第一次读取代码后,实例化该列表一次,然后反复使用相同的实例,如本示例所示:
>>> def foo(bar=[]):
... bar.append(1)
... print(bar)
...
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]
>>> bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined
您应该这样启动函数:
def dfs_dict(graph, curr, val, path=None):
if path is None:
path = []
编辑:而且,由于列表是可变的,因此您可能应该在
dfs_dict
的开头进行复制,以便在添加项目时不修改使用“父”堆栈框架的副本。关于python - Python参数范围-相同的对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22136135/