如何在迭代时从字典中删除项目?
在迭代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}