
Python字典在遍历时**不能安全地直接增删键值对**,否则会触发 RuntimeError: dictionary changed size during iteration(字典在迭代期间被修改大小)。
为什么遍历时修改会报错
Python 字典的迭代器在创建时会记录当前哈希表的状态(如桶数量、元素分布)。如果在遍历过程中插入或删除键,字典底层可能触发扩容、缩容或重哈希,导致迭代器失去同步,解释器为避免未定义行为而主动抛出异常。
注意:仅修改已有键的值(d[key] = new_value)是允许的,不改变字典结构,不会报错。
安全修改的常用方法
若需在遍历逻辑中增删键值对,应避开「边迭代边改原字典」的方式:
立即学习“Python免费学习笔记(深入)”;
- 先收集待操作的键,再统一处理:遍历字典获取要删除或修改的键列表,遍历结束后再执行删除或新增;
-
用字典推导式生成新字典:适合过滤或映射场景,例如
new_d = {k: v*2 for k, v in d.items() if v > 0}; -
转为 list 再遍历:用
list(d.keys())或list(d.items())创建快照,此时修改原字典不影响迭代过程; - 使用 while + popitem()(仅适用于逐个移除):适用于清空或按需提取场景,但顺序不保证。
常见误写与正确写法对比
错误示例(运行时报错):
d = {'a': 1, 'b': 2, 'c': 3}
for k in d:
if k == 'b':
del d[k] # RuntimeError!正确示例(安全删除):
d = {'a': 1, 'b': 2, 'c': 3}
keys_to_delete = [k for k in d if k == 'b']
for k in keys_to_delete:
del d[k] # OK或更简洁地:
d = {k: v for k, v in d.items() if k != 'b'}特别注意嵌套修改场景
如果字典值本身是可变对象(如列表、另一个字典),修改其内部内容(如 d['x'].append(1) 或 d['y']['z'] = 5)是完全安全的——这不改变外层字典的键集合或大小,只是修改值对象的状态。










