【问题标题】:Python DFS recursive function retaining values from previous callPython DFS递归函数保留先前调用的值
【发布时间】:2019-01-07 09:47:17
【问题描述】:

如果标题有误导性,我很抱歉,但我不能以任何其他方式表示。
我正在尝试实现 bfs 和 dfs 以记住一些概念,但是代码的递归版本会出现奇怪的行为。

这是正在发生的事情:

def rec_dfs(g, start_node, visited=[]):
    visited.append(start_node)
    for next_node in g[start_node]:
        if next_node not in visited:
            rec_dfs(g, next_node, visited)
    return visited

graph2={'A': ['B', 'C', 'D'],
       'B': ['A', 'E', 'F'],
       'C': ['A', 'F'],
       'D': ['A'],
       'E': ['B'],
       'F': ['B', 'C']}

rec_dfs(graph2, "A") #['A', 'B', 'E', 'F', 'C', 'D']               OK
rec_dfs(graph2, "A") #['A', 'B', 'E', 'F', 'C', 'D', 'A']          NOK
rec_dfs(graph2, "A") #['A', 'B', 'E', 'F', 'C', 'D', 'A', 'A']     NOK

它应该总是返回第一个案例,但是当我调查时,我可以看到第二个调用已经填充了“已访问”。

如果我这样调用函数:

rec_dfs(graph2, "A", []) #['A', 'B', 'E', 'F', 'C', 'D']  OK
rec_dfs(graph2, "A", []) #['A', 'B', 'E', 'F', 'C', 'D']  OK
rec_dfs(graph2, "A", []) #['A', 'B', 'E', 'F', 'C', 'D']  OK

它工作得很好......
如果有人能解释为什么会发生这种行为,以及是否有办法避免这种情况,我将不胜感激。

谢谢!

【问题讨论】:

  • 真的很奇怪,看起来本地 kwargs 字典中的访问数组由于某种原因是全局的。顺便说一句,它是什么版本的 python?
  • 好吧,真的很有趣。从头开始我说的那些 kwargs。事实证明,可变默认参数在调用之间保存状态,并且它们仅在函数定义期间被初始化。 code.activestate.com/recipes/577786-smarter-default-arguments。因此,之后进行这 2 个调用与使用相同状态进行更多递归没有什么不同。如果你想重置状态,你必须明确地重新初始化数组。
  • 哇,从没想过python会那样做哈哈哈......但是非常感谢@GregK..如果你不介意,回答这个问题,我可以接受这个答案:) BTW,Python 3.6 .5

标签: python recursion graph breadth-first-search microsoft-distributed-file-system


【解决方案1】:

您正在使用visited 数组作为可变默认参数,根据http://code.activestate.com/recipes/577786-smarter-default-arguments/ 定义,它本质上只初始化为空数组一次。

在每次后续调用rec_dfs() 期间,如果visited 数组未显式重新初始化,它将在每次后续函数调用期间保持其状态。

【讨论】:

  • 谢谢!我想知道是否有任何方法可以避免这种情况,使数组自行重新初始化,而不是显式传递它
  • 不确定是否有任何pythonic方式来做类似的事情,但由于它有这种行为,我认为这是无法避免的。恕我直言,它仍然非常优雅,并将 dfs 开始调用与递归调用区分开来
猜你喜欢
  • 2013-11-06
  • 2023-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
  • 2013-11-27
  • 2023-04-04
相关资源
最近更新 更多