在Python中,我可以在遍历字典时删除字典中的项吗?

我想从字典中删除不符合特定条件的元素,而不是创建一个全新的字典。以下是一个好的解决方案,还是有更好的方法?

for k, v in mydict.items():
    if k == val:
        del mydict[k]

当前回答

对于Python 3+:

>>> mydict
{'four': 4, 'three': 3, 'one': 1}

>>> for k in list(mydict.keys()):
...     if mydict[k] == 3:
...         del mydict[k]

>>> mydict
{'four': 4, 'one': 1}

其他答案在Python 2中工作得很好,但在Python 3中会引发RuntimeError:

RuntimeError:在迭代过程中字典改变了大小。

这是因为mydict.keys()返回的是一个迭代器而不是一个列表。 正如在评论中指出的那样,只需将mydict.keys()转换为逐个列表的列表(mydict.keys()),它就应该工作。


对于Python 2:

在控制台中进行的一个简单测试显示,在遍历字典时不能修改它:

>>> mydict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}

>>> for k, v in mydict.iteritems():
...    if k == 'two':
...        del mydict[k]

------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

正如delnan的回答中所述,当迭代器试图移动到下一个条目时,删除条目会导致问题。相反,使用keys()方法获取键的列表并使用它:

>>> for k in mydict.keys():
...    if k == 'two':
...        del mydict[k]

>>> mydict
{'four': 4, 'three': 3, 'one': 1}

如果你需要根据items的值进行删除,请使用items()方法:

>>> for k, v in mydict.items():
...     if v == 3:
...         del mydict[k]

>>> mydict
{'four': 4, 'one': 1}

其他回答

相反,迭代一个副本,例如items()返回的副本:

for k, v in list(mydict.items()):

如果想要删除的项总是在dict迭代的“开始”,有一种方法可能是合适的

while mydict:
    key, value = next(iter(mydict.items()))
    if should_delete(key, value):
       del mydict[key]
    else:
       break

“开头”只保证在某些Python版本/实现中是一致的。例如,来自Python 3.7新提示

dict对象的插入顺序保存特性已被声明为Python语言规范的正式组成部分。

这种方法避免了许多其他答案所建议的字典副本,至少在Python 3中是这样。

我在Python3中尝试了上述解决方案,但在字典中存储对象时,这一个似乎是唯一适合我的解决方案。基本上,您可以创建dict()的副本,并在删除原始字典中的条目的同时遍历该副本。

        tmpDict = realDict.copy()
        for key, value in tmpDict.items():
            if value:
                del(realDict[key])

在python3中,迭代dic.keys()将引发字典大小错误。你可以用这种替代方式:

使用python3测试,它工作正常,并且没有引发错误“迭代期间字典更改大小”:

my_dic = { 1:10, 2:20, 3:30 }
# Is important here to cast because ".keys()" method returns a dict_keys object.
key_list = list( my_dic.keys() )

# Iterate on the list:
for k in key_list:
    print(key_list)
    print(my_dic)
    del( my_dic[k] )


print( my_dic )
# {}

你可以使用字典理解法。

D = {k: D [k] for k in D if D [k] != val}