在遍历字典时如何删除其中的项?

434 投票
12 回答
270112 浏览
提问于 2025-04-16 14:09

我可以在遍历Python字典的时候删除里面的项目吗?

我想把那些不符合某个条件的元素从字典里去掉,而不是重新创建一个新的字典。下面这个方法好不好,还是有没有更好的办法呢?

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

12 个回答

35

可以遍历一个副本,比如用 items() 返回的那个副本:

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

你也可以分两步来做:

remove = [k for k in mydict if k == val]
for k in remove: del mydict[k]

我最喜欢的方法通常是直接创建一个新的字典:

# Python 2.7 and 3.x
mydict = { k:v for k,v in mydict.items() if k!=val }
# before Python 2.7
mydict = dict((k,v) for k,v in mydict.iteritems() if k!=val)
440

对于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()返回的是一个迭代器,而不是一个列表。正如评论中提到的,只需通过list(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()方法会更合适:

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

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

撰写回答