【问题标题】:Python argument scope - same objects?Python参数范围 - 相同的对象?
【发布时间】:2014-03-03 01:22:55
【问题描述】:

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

【问题讨论】:

    标签: python python-2.7 python-3.x scope arguments


    【解决方案1】:

    问题是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 的开头复制一份,以免在追加项目时修改使用“父”堆栈框架的那个。

    【讨论】:

    • 我原以为参数是在调用函数时实例化的,而不是在第一次读取代码时。感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 2015-06-10
    相关资源
    最近更新 更多