
在 Python 中,对字典(dict)进行遍历时直接修改其键或值,行为取决于修改的类型:修改**值**是安全的;修改**键**(如增删元素)会触发 RuntimeError: dictionary changed size during iteration 异常。
修改字典的值是允许的
遍历过程中更新已有键对应的值,不会影响迭代器,Python 允许这样做:
data = {'a': 1, 'b': 2, 'c': 3}
for k in data:
data[k] *= 10 # ✅ 合法:只改 value
print(data) # {'a': 10, 'b': 20, 'c': 30}
增删键(改变字典大小)会报错
只要在循环中调用 del data[k]、data.pop(k)、data.clear() 或新增键(如 data['new'] = 4),都会导致运行时错误:
data = {'a': 1, 'b': 2}
for k in data:
del data[k] # ❌ RuntimeError: dictionary changed size during iteration
这是因为 Python 的字典迭代器在开始时会记录当前哈希表的“版本号”(dict->ma_version_tag),一旦检测到结构变化(如 resize、key 删除/插入),就立即抛出异常,防止未定义行为。
立即学习“Python免费学习笔记(深入)”;
安全修改键的常用做法
如果确实需要在遍历时增删键,应避免直接修改原字典。推荐以下方式:
-
先收集要操作的键,再统一处理:例如用
list(d.keys())创建快照,再遍历这个列表去删/改原字典 -
使用字典推导式重建:适合过滤或转换场景,如
new_d = {k: v*2 for k, v in d.items() if v > 0} -
用
copy()或list(d.items())遍历副本:不修改原字典结构,仅读取后另作处理
注意:.keys()/.values()/.items() 返回视图,不是拷贝
虽然 d.keys() 看似返回一个“集合”,但它只是动态视图——若你在遍历 d.keys() 时修改 d,依然会报错:
for k in data.keys(): # 这里仍是活视图,非 list
del data[k] # ❌ 同样报错
真正安全的是显式转成列表:for k in list(data.keys()): ...









