繁体   English   中英

字典大小在迭代过程中更改(运行时错误)

[英]dictionary size changed during iteration (Runtime error)

我收到RuntimeError:字典在迭代过程中更改了大小,我经历了一些堆栈溢出的帖子,发现当您在循环(插入/删除)时修改字典的大小时会发生这种情况。

但是就我而言,我只是遍历字典,所以我不确定为什么会收到错误。

我发现使用非集合字典时没有出现任何问题,但是这使得添加新顶点比使用集合复杂得多。

我知道我可能会制作一个字典的深层副本并对其进行迭代,但是我想首先了解为什么首先会出现此错误。

我在下面的示例中剪切了大多数非必要代码。

from collections import defaultdict 


class Graph: 

    def __init__(self,vertices): 

        self.graph = defaultdict(list)  

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

    def fillOrder(self,v,visited, stack): 

        visited.add(v)
        for neighbour in self.graph[v]:
          if neighbour not in visited:
            self.fillOrder(neighbour, visited, stack)
        stack.append(v)


    def printSCCs(self): 

        stack = [] 

        visited = set()

        for key in self.graph:
          print(key)
          self.fillOrder(key, visited, stack)

g = Graph(5) 
g.addEdge(1, 0) 
g.addEdge(0, 2) 
g.addEdge(2, 1) 
g.addEdge(0, 3) 
g.addEdge(3, 4) 
g.printSCCs() 

我预计不会引发任何错误,并且堆栈中将填充图中的顶点。

您使用的是defaultdict因此如果您尝试访问不存在的条目,则在隐式插入中存在。

尤其是:

def fillOrder(self,v,visited, stack): 
    # ...
    for neighbour in self.graph[v]:
        # ...

您的键v不能保证存在,因此对self.graph[v]的访问导致将新条目添加到字典中。 如果用普通字典替换defaultdict并在addEdge按需创建新列表,那么更明显的是失败了:

1
Traceback (most recent call last):
  File "test.py", line 38, in <module>
    g.printSCCs()
  File "test.py", line 30, in printSCCs
    self.fillOrder(key, visited, stack)
  File "test.py", line 21, in fillOrder
    self.fillOrder(neighbour, visited, stack)
  File "test.py", line 21, in fillOrder
    self.fillOrder(neighbour, visited, stack)
  File "test.py", line 21, in fillOrder
    self.fillOrder(neighbour, visited, stack)
  File "test.py", line 19, in fillOrder
    for neighbour in self.graph[v]:
KeyError: 4

如果要保证两个边缘端点都在字典中,则可能需要修改addEdge来执行以下操作:

self.graph[u].append(v) 
self.graph[v].append(u) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM