我正在编写一个简单的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/

10-14 17:44