安全删除字典元素需避免边遍历边修改原结构,推荐用字典推导式重建;也可遍历keys列表副本、预收集键后pop、或用filter+dict构造,各适用不同场景。

遍历字典时直接删元素会报 RuntimeError: dictionary changed size during iteration,因为 Python 禁止在迭代原字典的同时修改其大小。安全删除的关键是“不边遍历边改原结构”。下面几种写法都可靠,适用场景略有不同。
用字典推导式重建(最推荐)
本质是创建新字典,过滤掉不需要的键值对,原字典被覆盖或赋给新变量。代码简洁、可读性强,且完全规避运行时风险。
- 适合条件明确、一次性过滤的场景,比如“删掉所有 value 为 None 或小于阈值的项”
- 语法:
my_dict = {k: v for k, v in my_dict.items() if 条件} - 注意:这不是“原地修改”,而是新建对象;若其他变量引用原字典,它们不会同步更新
遍历 keys 列表副本(通用稳妥)
把 dict.keys() 转成 list 再遍历,因 list 是静态快照,删原字典不影响循环过程。
- 写法简单,兼容所有 Python 版本,逻辑直白
- 常用组合:
for k in list(my_dict): if 条件: del my_dict[k]或my_dict.pop(k, None) - 比推导式略多一行,但保留原字典对象身份(id 不变),适合需维持引用一致性的场合
用 pop() 配合预收集键列表
先扫描一遍,把要删的键存进一个临时列表,再单独遍历该列表执行 pop()。
- 语义清晰,便于调试(可打印待删键再确认)
-
pop(key, default)自带容错,即使键意外不存在也不会报错 - 适合删除逻辑较复杂、需多次判断或跨字段关联的场景
用 filter + dict 构造(函数式风格)
借助 filter() 和生成器表达式,再转为字典。虽不如推导式常用,但体现函数式思路。
- 示例:
my_dict = dict(filter(lambda kv: kv[1] >= 75, my_dict.items())) - 可读性稍弱,性能与推导式接近,但无明显优势,一般优先选推导式
- 适合已习惯函数式编程、或需复用 filter 逻辑的项目










