In the code I wrote, an error called RuntimeError: dictionary changed size during iteration occurred in the for i in graph part. although I did not change the graph dictionary at all. I experimented with this as well as if it wasn't possible to use defaultdict in the for statement, but it worked well, the code I experimented is also attached, so can I know why this error came out?
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
experiment code
a = defaultdict(list)
a[1] = [3,4,5]
a[2]
for q in a:
print(q)
"""
OUTPUT : 1,2
"""
I can see how your code can add items to graph
inside the loop in question...
You are iterating over the items in graph
. So let's say graph
looks like this:
graph = [g1, g2, g3]
So the loop calls _dfs(g1)
. Then, inside _dfs
, there's this line:
for e in graph[i]:
so that line is iterating over graph[g1]
. That's fine, because that entry exists in graph
. But what is in graph[g1]
? We don't know. Let's assume the first key in that collection is x1
. So now e
is graph[g1][x1]
. Then, _dfs
is called again, with this new e
:
_dfs(e)
Then inside _dfs
, we again do:
for e in graph[i]:
but this time i
is graph[g1][x1]
, the prior e
that was passed in as the parameter to _dfs
. So this line is really:
for e in graph[graph[g1][x1]]
We don't know what graph[g1][x1]
is. We can't assume that it is a key in graph
. If it isn't, then because graph
is a defaultdict
, an entry is added to graph
for the key graph[g1][x1]
, with an empty list as the key. This is when graph
changes size.
If graph[g1][x1]
were already in graph
, then I believe that this code would recurse forever.
I don't understand your logic since you haven't shown us the incoming data passed in as prerequisites
. Looking just at the code, I can't think of how calling _dfs
recursively, and therefore needing items in the value lists of graph
to also be keys in graph
, would ever make sense. I would suggest that you rethink this aspect of your algorithm.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.