如何避免“RuntimeError:字典在迭代期间改变大小”错误?

时间:2012-08-13 20:30:08

标签: python list dictionary loops

我已经检查了所有其他问题但是找到了相同的错误但没有找到有用的解决方法= /

我有一份清单词典:

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

其中一些值为空。在创建这些列表的最后,我想在返回字典之前删除这些空列表。目前我试图这样做如下:

for i in d:
    if not d[i]:
        d.pop(i)

然而,这给了我运行时错误。我知道你在迭代它时不能在字典中添加/删除元素......这会是什么方法呢?

12 个答案:

答案 0 :(得分:317)

在Python 2.x中,调用keys会复制您在修改dict时可以迭代的键:

for i in d.keys():

请注意,这在Python 3.x中不起作用,因为keys返回迭代器而不是列表。

另一种方法是使用list强制创建密钥的副本。这个也适用于Python 3.x:

for i in list(d):

答案 1 :(得分:29)

只需使用字典理解将相关项目复制到新的字典中

>>> d
{'a': [1], 'c': [], 'b': [1, 2], 'd': []}
>>> d = { k : v for k,v in d.iteritems() if v}
>>> d
{'a': [1], 'b': [1, 2]}

答案 2 :(得分:27)

您只需要使用“复制”:

通过这种方式,您可以迭代原始字典字段,并且可以动态更改所需的字典(d dict)。 它适用于每个python版本,所以它更清晰。

In [1]: d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

In [2]: for i in d.copy():
   ...:     if not d[i]:
   ...:         d.pop(i)
   ...:         

In [3]: d
Out[3]: {'a': [1], 'b': [1, 2]}

答案 3 :(得分:11)

我会尽量避免首先插入空列表,但通常会使用:

d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty

如果在2.7之前:

d = dict( (k, v) for k,v in d.iteritems() if v )

或只是:

empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
    del[k]

答案 4 :(得分:9)

对于Python 3:

{k:v for k,v in d.items() if v}

答案 5 :(得分:4)

这对我有用:

dict = {1: 'a', 2: '', 3: 'b', 4: '', 5: '', 6: 'c'}
for key, value in list(dict.items()):
    if (value == ''):
        del dict[key]
print(dict)
# dict = {1: 'a', 3: 'b', 6: 'c'}  

将字典项投射到列表中会创建其项列表,因此您可以对其进行迭代并避免使用RuntimeError

答案 6 :(得分:1)

在这种情况下,我想制作一个深层副本并在修改原始字典的同时循环浏览该副本。

如果查找字段在列表中,则可以在列表的for循环中枚举,然后将位置指定为索引以访问原始字典中的字段。

答案 7 :(得分:1)

dictc = {“ stName”:“ asas”} keys = dictc.keys() 用于列表中的键(键): dictc [key.upper()] ='新值' 打印(str(dictc))

答案 8 :(得分:1)

避免“在迭代错误期间字典改变大小” 只需将 'list' 与 '.items()' 一起使用,这是一个简单的示例:

my_dict = {
    'k1':1,
    'k2':2,
    'k3':3,
    'k4':4
 
    }
    
print(my_dict)

for key, val in list(my_dict.items()):
    if val == 2 or val == 4:
        my_dict.pop(key)

print(my_dict)

+++ 输出:

{'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}

{'k1': 1, 'k3': 3}

+++

这只是示例并根据您的情况/要求进行更改, 我希望这会有所帮助。

答案 9 :(得分:0)

运行时错误的原因是,您无法在迭代期间更改数据结构时对其进行遍历。

获得所需内容的一种方法是使用列表附加要删除的键,然后在字典中遍历列表时在字典上使用pop函数删除标识的键。

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
pop_list = []

for i in d:
        if not d[i]:
                pop_list.append(i)

for x in pop_list:
        d.pop(x)
print (d)

答案 10 :(得分:0)

在for循环中更改字典时,无法迭代字典。进行投射以列出并遍历该列表,它对我有用。

    for key in list(d):
        if not d[key]: 
            d.pop(key)

答案 11 :(得分:0)

Python 3不允许在迭代(使用上面的循环)字典时删除。有多种选择可以做;一种简单的方法是更改​​以下行

for i in x.keys():

使用

for i in list(x)