![](/img/trans.png)
[英]How to fix this python error? RuntimeError: dictionary changed size during iteration
[英]How to avoid "RuntimeError: dictionary changed size during iteration" error?
我有一个列表字典,其中一些值为空:
d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
在创建这些列表的最后,我想在返回我的字典之前删除这些空列表。 我试着这样做:
for i in d:
if not d[i]:
d.pop(i)
但我得到了一个RuntimeError
。 我知道在遍历字典时不能添加/删除字典中的元素……那么有什么办法解决这个问题呢?
请参阅在迭代 Python dict 时修改它以获取可能导致问题的引用以及原因。
您只需要使用copy
:
这样,您可以遍历原始字典字段,并且可以动态更改所需的 dict d
。 它适用于每个 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]}
(顺便说一句 - 通常迭代您的数据结构的副本,而不是使用.copy
用于字典或切片[:]
用于列表,您可以使用import copy
-> copy.copy
(对于浅拷贝,相当于受支持的copy
通过列表支持的字典或切片[:]
)或您的数据结构上的copy.deepcopy
。)
只需使用字典理解将相关项目复制到新字典中:
>>> 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]}
为此在 Python 2 中:
>>> 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]}
这对我有用:
d = {1: 'a', 2: '', 3: 'b', 4: '', 5: '', 6: 'c'}
for key, value in list(d.items()):
if value == '':
del d[key]
print(d)
# {1: 'a', 3: 'b', 6: 'c'}
将字典项转换为 list 会创建其项的列表,因此您可以对其进行迭代并避免RuntimeError
。
我会尽量避免首先插入空列表,但是,通常会使用:
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]
对于 Python 3:
{k:v for k,v in d.items() if v}
以避免“迭代错误期间字典更改大小”。
例如:“当您尝试删除某个键时”,
只需将 '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}
+++
这只是示例,并根据您的案例/要求进行更改,我希望这会有所帮助。
您不能在 for 循环期间更改字典时迭代字典。 制作一个列表并迭代该列表,它对我有用。
for key in list(d):
if not d[key]:
d.pop(key)
Python 3 不允许在迭代(使用上面的 for 循环)字典时删除。 有多种选择; 一种简单的方法是更改以下行
for i in x.keys():
和
for i in list(x)
运行时错误的原因是,当数据结构在迭代过程中发生变化时,您无法迭代数据结构。
实现您正在寻找的一种方法是使用 list 来附加您要删除的键,然后在字典上使用 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)
dictc={"stName":"asas"}
keys=dictc.keys()
for key in list(keys):
dictc[key.upper()] ='New value'
print(str(dictc))
对于这样的情况,我喜欢在修改原始字典时制作一个深层副本并循环遍历该副本。
如果查找字段在列表中,则可以在列表的for循环中枚举,然后将位置指定为索引以访问原始dict中的字段。
如果字典中的值也是唯一的,那么我使用了这个解决方案
keyToBeDeleted=None
for k,v in mydict.items():
if(v==match):
keyToBeDeleted=k
break
mydict.pop(keyToBeDeleted,None)
Python “RuntimeError: dictionary changed size during iteration”发生在我们在迭代时改变字典的大小时。
要解决该错误,请使用 copy() 方法创建可以迭代的字典的浅表副本,例如my_dict.copy()
。
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in my_dict.copy():
print(key)
if key == 'b':
del my_dict[key]
print(my_dict) # 👉️ {'a': 1, 'c': 3}
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in list(my_dict.keys()):
print(key)
if key == 'b':
del my_dict[key]
print(my_dict) # 👉️ {'a': 1, 'c': 3}
嵌套 null 个值
假设我们有一个带有嵌套键的字典,其中一些是 null 值:
dicti = {
"k0_l0":{
"k0_l1": {
"k0_l2": {
"k0_0":None,
"k1_1":1,
"k2_2":2.2
}
},
"k1_l1":None,
"k2_l1":"not none",
"k3_l1":[]
},
"k1_l0":"l0"
}
然后我们可以使用这个 function 删除 null 值:
def pop_nested_nulls(dicti):
for k in list(dicti):
if isinstance(dicti[k], dict):
dicti[k] = pop_nested_nulls(dicti[k])
elif not dicti[k]:
dicti.pop(k)
return dicti
Output 用于pop_nested_nulls(dicti)
{'k0_l0': {'k0_l1': {'k0_l2': {'k1_1': 1,
'k2_2': 2.2}},
'k2_l1': 'not '
'none'},
'k1_l0': 'l0'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.