如何在迭代时从字典中删除项目?

在迭代Python的时候从Python字典中删除项目是否合法?

例如:

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

这个想法是从字典中移除不符合特定条件的元素,而不是创build一个新的字典,它是被迭代的一个子集。

这是一个很好的解决scheme? 有更优雅/有效的方法吗?

控制台中的一个简单testing显示,在迭代它时,不能修改字典:

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

你也可以分两步做:

 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) 

迭代时您不能修改集合。 这种方式是疯狂的 – 最显着的是,如果你被允许删除和删除当前的项目,迭代器将不得不继续(+1),下一个接下来的调用将带你超越(+2),所以, d最终跳过一个元素(在删除的元素后面)。 你有两个select:

  • 复制所有的键(或值,或两者,取决于你需要什么),然后遍历这些。 你可以使用.keys()等等(在Python 3中,将生成的迭代器传递给list )。 虽然可能是非常浪费的空间明智的。
  • 像平常一样迭代mydict ,将密钥保存在一个单独的集合to_delete 。 迭代mydict ,从mydict删除mydict所有项。 在第一种方法中保存一些(取决于删除多less个键和保留多less个键),但是还需要更多的线。

而不是遍历一个副本,比如items()返回的那个:

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

用python3迭代dic.keys()会引发字典大小错误。 您可以使用这种替代方法:

testing与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 ) # {} 

我使用它时,从一个字典使用很多的内存,我想构build一个其他字典(包含第一个修改),而不做“复制”和超载内存。

您可以先build立一个要删除的键列表,然后遍历该列表删除它们。

 dict = {'one' : 1, 'two' : 2, 'three' : 3, 'four' : 4} delete = [] for k,v in dict.items(): if v%2 == 1: delete.append(k) for i in delete: del dict[i] 

你可以使用字典理解。

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