【问题标题】:RuntimeError : dictionary changed size during iteration with defaultdict()RuntimeError:字典在迭代期间使用 defaultdict() 改变了大小
【发布时间】:2021-01-30 14:34:41
【问题描述】:

在我写的代码中,for i in graph部分出现了一个名为RuntimeError: dictionary changed size during iteration的错误。尽管我根本没有更改图形字典。这个我试验了一下,好像for语句中不能使用defaultdict,但是效果很好,我试验的代码也附上了,不知道为什么会出现这个错误?

def canFinish(numCourses: int, prerequisites:[[]]) -> bool:
        
        graph = collections.defaultdict(list)
        visited = set()
        
        for i in prerequisites:
            graph[i[0]].append(i[1])
        
        def _dfs(i):
            if i in visited:
                return False
            
            visited.add(i)
            for e in graph[i]:
                if not _dfs(e):
                    return False
            visited.remove(i)
            return True
            
        
        
        for i in graph:
            if not _dfs(i):
                return False
            
        return True
---------------------------------------------------------------------------
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-37-33d660346b1a> in <module>
----> 1 canFinish(3, [[0,1],[0,2],[1,2]])

<ipython-input-36-fd2cb0d8dafb> in canFinish(numCourses, prerequisites)
     20 
     21 
---> 22         for i in graph:
     23             if not _dfs(i):
     24                 return False

RuntimeError: dictionary changed size during iteration


实验代码

a = defaultdict(list)
a[1] = [3,4,5]
a[2]
for q in a:
    print(q)

"""
OUTPUT : 1,2
"""

【问题讨论】:

  • 你能发布完整的错误信息和回溯吗?
  • 我有点困惑,您刚刚编辑的错误与您在帖子中谈论的错误非常不同。我以为你在处理RuntimeError 而不是NameError?如果它只是一个NameError,那么确保from collections import defaultdict 位于任何.py 文件的顶部。
  • @BeanBagTheCat 我很抱歉。我又编辑了

标签: python


【解决方案1】:

我可以看到您的代码如何将项目添加到相关循环内的graph...

您正在迭代 graph 中的项目。所以假设graph 看起来像这样:

graph = [g1, g2, g3]

所以循环调用_dfs(g1)。然后,在_dfs 里面,有这样一行:

for e in graph[i]:

所以该行正在迭代graph[g1]。这很好,因为该条目存在于graph 中。但是graph[g1] 中有什么?我们不知道。 假设该集合中的第一个键是x1。所以现在egraph[g1][x1]。然后,再次调用_dfs,使用这个新的e

_dfs(e)

然后在_dfs 内部,我们再次这样做:

for e in graph[i]:

但是这次igraph[g1][x1],之前的e 作为参数传递给_dfs。所以这行真的是:

for e in graph[graph[g1][x1]]

我们不知道graph[g1][x1] 是什么。我们不能假设它是graph 中的一个键。如果不是,那么因为graphdefaultdict,所以会在graph 中添加一个条目以作为键graph[g1][x1],并以一个空列表作为键。这是graph 改变大小的时候。

如果graph[g1][x1] 已经在graph 中,那么我相信这段代码会永远递归。

我不明白你的逻辑,因为你没有向我们展示作为prerequisites 传入的传入数据。只看代码,我想不出如何递归调用_dfs,因此需要graph 的值列表中的项目也成为graph 中的键,这是有意义的。我建议您重新考虑算法的这一方面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2015-03-31
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多