繁体   English   中英

“RuntimeError:字典在迭代期间改变了大小”但它在循环中没有改变

[英]"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.

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