簡體   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