问题:如何避免“ RuntimeError:字典在迭代过程中更改大小”错误?

我检查了所有其他问题,并发现了相同的错误,但没有找到有帮助的解决方案= /

我有一个列表字典:

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

其中某些值为空。在创建这些列表的最后,我想在返回字典之前删除这些空列表。当前,我正在尝试执行以下操作:

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

但是,这给了我运行时错误。我知道您无法在字典中进行迭代时添加/删除字典中的元素…那么解决这个问题的方法是什么?

I have checked all of the other questions with the same error yet found no helpful solution =/

I have a dictionary of lists:

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

in which some of the values are empty. At the end of creating these lists, I want to remove these empty lists before returning my dictionary. Current I am attempting to do this as follows:

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

however, this is giving me the runtime error. I am aware that you cannot add/remove elements in a dictionary while iterating through it…what would be a way around this then?


回答 0

在Python 2.x中,调用keys会生成密钥的副本,您可以在修改时进行迭代dict

for i in d.keys():

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

另一种方法是用于list强制复制密钥。这也可以在Python 3.x中使用:

for i in list(d):

In Python 2.x calling keys makes a copy of the key that you can iterate over while modifying the dict:

for i in d.keys():

Note that this doesn’t work in Python 3.x because keys returns an iterator instead of a list.

Another way is to use list to force a copy of the keys to be made. This one also works in Python 3.x:

for i in list(d):

回答 1

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

>>> 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]}

为此,在Python 3

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

Just use dictionary comprehension to copy the relevant items into a new dict

>>> 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]}

For this in Python 3

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

回答 2

您只需要使用“复制”:

这样,您就可以遍历原始词典字段,并且可以随时更改所需的字典(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]}

You only need to use “copy”:

On that’s way you iterate over the original dictionary fields and on the fly can change the desired dict (d dict). It’s work on each python version, so it’s more clear.

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

我会尽量避免一开始就插入空列表,但是通常会使用:

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]

I would try to avoid inserting empty lists in the first place, but, would generally use:

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

If prior to 2.7:

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

or just:

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

回答 4

对于Python 3:

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

For Python 3:

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

回答 5

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

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

You cannot iterate through a dictionary while its changing during for loop. Make a casting to list and iterate over that list, it works for me.

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

回答 6

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

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

For situations like this, i like to make a deep copy and loop through that copy while modifying the original dict.

If the lookup field is within a list, you can enumerate in the for loop of the list and then specify the position as index to access the field in the original dict.


回答 7

这为我工作:

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

This worked for me:

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'}  

Casting the dictionary items to list creates a list of its items, so you can iterate over it and avoid the RuntimeError.


回答 8

dictc = {“ stName”:“ asas”} keys = dictc.keys()用于键入列表(键):dictc [key.upper()] =“新值” print(str(dictc))

dictc={“stName”:”asas”} keys=dictc.keys() for key in list(keys): dictc[key.upper()] =’New value’ print(str(dictc))


回答 9

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

实现所需内容的一种方法是,使用列表附加要删除的键,然后在字典中遍历列表时在字典上使用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)

The reason for the runtime error is that you cannot iterate through a data structure while its structure is changing during iteration.

One way to achieve what you are looking for is to use list to append the keys you want to remove and then use pop function on dictionary to remove the identified key while iterating through the list.

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

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

for i in x.keys():

for i in list(x)

Python 3 does not allow deletion while iterating (using for loop above) dictionary. There are various alternatives to do; one simple way is the to change following line

for i in x.keys():

With

for i in list(x)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。