【问题标题】:Python: Graph, DFS, set, defaultdict - error in changing dictionary sizePython:Graph、DFS、set、defaultdict - 更改字典大小时出错
【发布时间】:2018-05-30 20:59:29
【问题描述】:

当我尝试使用深度优先方法打印断开连接的图时,出现了这个问题。

我使用defaultdict 来表示图形的邻接列表。我知道如果某个键不在字典中,defaultdict 会添加它并提供您设置的任何默认值(在我的情况下为list)。

在您将此评论视为重复之前,我已阅读帖子 herehere。他们表明在迭代过程中字典正在被更改,但在我的特定情况下我不太明白。我没有从defaultdict 中弹出任何值。

代码改编自GeeksForGeeks,但我决定使用set 而不是list 来访问顶点,我将DFSUtil 函数重命名为DFSHelper。此外,正在打印的图形与下面的图形相同,只是我添加了一个指向节点 4 的节点 5。我尝试添加它以使图形真正断开连接。如果没有此附加条目,则不会产生错误。

这是我的代码:

from collections import defaultdict

class Graph:
  def __init__(self):
    self.graph = defaultdict(list)

  def addEdge(self, u, v):
    self.graph[u].append(v)

  def DFSHelper(self, vertex, visited):
    # recursively visit adjacent nodes
    if vertex not in visited:# and vertex in self.graph:
      visited.add(vertex)
      print(vertex)

      for neighbor in self.graph[vertex]:
        self.DFSHelper(neighbor, visited)

  def DFS(self): # for disconnected graph
    visited = set()

    # print(self.graph.keys())
    for vertex in self.graph.keys():
      if vertex not in visited:
        self.DFSHelper(vertex, visited)

    print('Visited : ', visited)

g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.addEdge(5, 4) # disconnected graph - I added this edge myself

print(g.graph)
print("Following is DFS of a disconnected graph")
g.DFS()

我注意到当我将 DFSHelper 中的第一行更改为:

if vertex not in visited:

if vertex not in visited and vertex in self.graph:

错误会消失,但我不明白为什么会这样。我的假设是在defaultdict 中搜索不是键的顶点4,并且由于defaultdict 的默认操作是创建一个条目而不是返回键错误,因此defaultdict 在迭代期间被更改。但是,我看不到 4 是如何传递到函数 defaultdict 中的。

这是有错误的输出。

Following is DFS of a disconnected graph
0
1
2
3
5
4
Traceback (most recent call last):
  File "depth-first-search-disconnected_graph.py", line 41, in <module>
    g.DFS()
  File "depth-first-search-disconnected_graph.py", line 25, in DFS
    for vertex in self.graph.keys():
RuntimeError: dictionary changed size during iteration

注意正在打印的 4。

这是解决了错误的输出。

Following is DFS of a disconnected graph
0
1
2
3
5
Visited :  {0, 1, 2, 3, 5}

【问题讨论】:

  • [dfs] 不是正确的标签:"DFS 是微软的分布式文件系统。注意:关于深度优先搜索的问题,请使用深度优先搜索标签。*不要与 [depth-first-search]"* 混淆
  • 我做出了改变。

标签: python dictionary graph depth-first-search defaultdict


【解决方案1】:

当你到达 4 和 5 的边缘时,你会在代码到达 for neighbor in self.graph[vertex] 时穿过 5 的邻居。 5 的唯一邻居是 4,然后您以 4 作为顶点递归调用该函数。在DFSHelper 的下一次调用中,defaultdict 为 4 添加了一个条目,因为它丢失了。

只需在 for 循环之前添加条件 if vertex in self.graph 即可避免此错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多