You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用一个字典过滤另一个字典?迭代时字典大小变更报错排查

解决字典迭代时修改导致的"迭代期间字典大小已更改"错误

我需要基于两个字典A和B创建第三个字典C,要求C包含A的全部键值对,但移除B中指定的键值对。我写了如下代码:

A = {"A": {"B": 6, "C": 5}, "B": {"A": 6, "D": 7, "E": 5}, "C": {"A": 5}, "D": {"B": 7, "E": 10, "H": 25},
     "E": {"D": 10, "F": 14, "B": 5}, "F": {"E": 14}, "H": {"D": 25}}
B = {"A": "C"}

C = A

for key, value in A.items():
     C.update({key: value})
     if key in B:
          for i in value:
               if i not in B.values():
                    C[key].pop(i)

print(C)

预期输出是:

{"A": {"B": 6}, "B": {"A": 6, "D": 7, "E": 5}, "C": {"A": 5}, "D": {"B": 7, "E": 10, "H": 25}, "E": {"D": 10, "F": 14, "B": 5}, "F": {"E": 14}, "H": {"D": 25}}

但运行时终端报错:迭代期间字典大小已更改


错误原因

  1. 引用赋值导致原字典被修改:C = A不是创建新字典,而是让C和A指向同一个字典对象。后续修改C的同时也会修改A,而你正在迭代A的键值对,这会干扰迭代过程。
  2. 迭代字典时修改其大小:内层循环for i in value中,value是A[key](和C[key]是同一个子字典),执行pop(i)会直接修改这个子字典的大小,Python不允许在迭代字典的同时修改其大小,因此抛出错误。

修正方案

  1. 对A进行深拷贝得到C,确保修改C不会影响原字典A。
  2. 迭代子字典键的副本(比如转成列表),这样即使原字典大小改变,迭代的是固定的副本,不会触发错误。

修正后的代码:

import copy

A = {"A": {"B": 6, "C": 5}, "B": {"A": 6, "D": 7, "E": 5}, "C": {"A": 5}, "D": {"B": 7, "E": 10, "H": 25},
     "E": {"D": 10, "F": 14, "B": 5}, "F": {"E": 14}, "H": {"D": 25}}
B = {"A": "C"}

# 深拷贝A得到独立的C
C = copy.deepcopy(A)

for key, value in C.items():
    if key in B:
        # 迭代子字典键的副本,避免迭代时修改字典大小
        for i in list(value.keys()):
            if i != B[key]:
                C[key].pop(i)

print(C)

代码说明

  • copy.deepcopy(A):完全复制A的所有层级结构,C成为独立的字典,修改C不会影响A。
  • list(value.keys()):将子字典的键转换成列表,迭代这个固定的列表,即使后续pop修改子字典,也不会影响迭代过程。
  • 直接判断i != B[key]比i not in B.values()更精准,因为B中每个key对应唯一要保留的子键。

内容的提问来源于stack exchange,提问作者Isabel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:02:42