[英]"RuntimeError: dictionary changed size during iteration" but it's not changed in the loop
我正在解决这个 LeetCode 问题,这是我的代码:
class Solution:
def alienOrder(self, words: List[str]) -> str:
adjacent = defaultdict(set)
for i in range(1, len(words)):
w1, w2 = words[i - 1], words[i]
min_len = min(len(w1), len(w2))
if len(w1) > len(w2) and w1[:min_len] == w2[:min_len]:
return ""
for j in range(min_len):
if w1[j] != w2[j]:
adjacent[w1[j]].add(w2[j]) # modify, not in the loop causing error
break
visited = dict()
res = []
def dfs(c):
if c in visited:
return visited[c]
visited[c] = True
for neighbor in adjacent[c]: # read only
if dfs(neighbor):
return True
visited[c] = False
res.append(c)
return False
for c in adjacent: # RuntimeError: dictionary changed size during iteration
if dfs(c):
return ''
return ''.join(reversed(res))
for c in adjacent
行抛出“RuntimeError: dictionary changed size during iteration”,我不明白。 我没有修改dfs()
中的adjacent
,对吗?
主要问题是当调用 dfs 方法时它使用这一行
for neighbor in adjacent[c]:
如果它存在于defaultdict中,这只会返回关联的值,如果它不存在,它会在您尝试访问不存在的键时创建并添加一个键
可能的解决方案:尝试检查该密钥是否已经存在,然后只启动循环这样的东西
if c in adjacent:
for neighbor in adjacent[c]:
......
function dfs()
通过添加键来修改visited()
字典。
具体来说,这一行:
visited[c] = True
将始终将c
添加到字典中,因为您检查c
是否在此行上方的已访问字典中。
如果您事先知道可能的键,则可以通过将每个键插入到已visited
字典中的值为False
来规避此问题。 (不幸的是,这个问题只有在你拥有 LeetCode Premium 时才会出现,所以我不能提出任何可以肯定地通过 LeetCode 的所有测试用例的建议。)
@gilf0yle 指出问题在于defaultdict
可能会插入新键。 解决方案是通过转换为普通dict
在迭代之前“冻结”它
adjacent = dict(adjacent) # No more default key insertion from here on
for c in adjacent:
if dfs(c):
return ''
return ''.join(reversed(res))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.