首页 > 解决方案 > 迭代时更新字典

问题描述

有没有办法在迭代期间更新字典以避免 RuntimeError: dictionary changed size during iteration

如果条件满足,我想要做的是在内部字典中弹出一些键。例如给定以下字典:

D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}

我想要得到的是:

D = {'a': {'s': 1,'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}

请注意,in's''b'字典值'a'键在内部字典中消失了,因为aD 中已经有一个值键,其 has's''b'as 值。

到目前为止我尝试了什么:

for k, v in D.items():
    for i, j in v.items():
        if i in D and k in D[i]:
            D.pop(i)

条件应该检查​​是否在内部字典中假设's'内部字典已经有一个'key'实际上是一个'key'字典D。这里没有考虑顺序。所以's'内部字典'a'应该被删除,因为有一个D['a']实际上有一个's'内部字典。相同的逻辑适用于'b'内部字典,因为有一个'a' keyin inner'b'D['a']has 'b',我会删除'a'D['b']保留D['a']['b']

但这会导致我弹出我想要保留的项目。既然我打算使用一本大词典,那么这里最好的选择是什么?

标签: python-3.xdictionary

解决方案


如果我理解正确,您想删除 D 的内部字典中已在 D 中定义键的每个条目。请注意,您将字典视为此处的有序序列,即使 Python 字典本质上是 un -订购。

与其在迭代现有字典时尝试修改它,不如创建一个新字典并在for循环中将值附加到它。

工作实施:

D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}
newdict = {}

for k_outer,v_outer in D.items():
    newdict[k_outer] = {}
    for k_inner,v_inner in v_outer.items():
        if k_inner not in newdict.keys():
            newdict[k_outer][k_inner] = v_inner

print(newdict)
D = newdict

输出:

{'a': {'s': 1, 'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}

或者,如果您绝对想动态修改 D,则使用.copy()which 允许您在修改循环内的原始字典时迭代原始字典的副本:

D = {'a': {'s': 1,'b': 2}, 's': {'a': -1, 'c': 3}, 'b': {'z': 2, 'x': 4, 'a': -2}}

seen = []

for k_outer,v_outer in D.copy().items():
    seen.append(k_outer)
    for k_inner,v_inner in v_outer.copy().items():
        if k_inner in seen:
            D[k_outer].pop(k_inner)

print(D)

输出:

{'a': {'s': 1, 'b': 2}, 's': {'c': 3}, 'b': {'z': 2, 'x': 4}}

推荐阅读