410

我检查了所有其他具有相同错误的问题,但没有找到有用的解决方案 =/

我有一个列表字典:

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

其中一些值为空。在创建这些列表结束时,我想在返回我的字典之前删除这些空列表。目前我正在尝试按如下方式执行此操作:

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

但是,这给了我运行时错误。我知道您在遍历字典时无法在字典中添加/删除元素......那么有什么办法解决这个问题?

4

12 回答 12

655

在 Python 3.x 和 2.x 中,您可以使用 uselist来强制制作密钥的副本:

for i in list(d):

在 Python 2.x 中,调用keys创建了密钥的副本,您可以在修改 时对其进行迭代dict

for i in d.keys():

但请注意,在 Python 3.x 中,第二种方法对您的错误没有帮助,因为keys它返回一个视图对象,而不是将键复制到列表中。

于 2012-08-13T20:33:21.450 回答
98

您只需要使用“复制”:

这样您就可以遍历原始字典字段,并且可以动态更改所需的字典(d 字典)。它适用于每个 python 版本,所以更清楚。

(顺便说一句 - 通常迭代你的数据结构的副本,而不是使用“.copy”作为“dict”或切片“[:]”作为“list”,你可以使用import copy-> copy.copy(对于相当于“copy”的浅拷贝" 由 "dict" 支持或切片 "[:]" 由 "list" 支持)或copy.deepcopy在您的数据结构上)。

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]}
于 2016-03-31T10:35:48.013 回答
61

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

>>> 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]}
于 2012-08-13T20:38:00.337 回答
21

这对我有用:

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.

于 2020-01-31T09:05:44.443 回答
13

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

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]
于 2012-08-13T20:42:10.400 回答
12

对于 Python 3:

{k:v for k,v in d.items() if v}
于 2016-01-14T16:14:07.930 回答
9

您不能在 for 循环期间更改字典时迭代字典。制作一个列表并迭代该列表,它对我有用。

    for key in list(d):
        if not d[key]: 
            d.pop(key)
于 2019-05-17T09:28:31.323 回答
9

以避免“迭代错误期间字典更改大小”。

例如:“当您尝试删除某个键时”,

只需将 '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}

+++

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

于 2021-03-19T22:59:26.893 回答
2

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

for i in x.keys():

for i in list(x)
于 2019-12-26T22:23:53.150 回答
1

运行时错误的原因是,当数据结构在迭代过程中发生变化时,您无法迭代数据结构。

实现您正在寻找的一种方法是使用 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)
于 2018-10-06T21:00:28.953 回答
1
dictc={"stName":"asas"}
keys=dictc.keys()
for key in list(keys):
    dictc[key.upper()] ='New value'
print(str(dictc))
于 2020-03-15T08:11:00.333 回答
0

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

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

于 2018-10-30T20:41:08.113 回答