2016-12-06 110 views
0

我想删除一个for循环字典中的一些项目,然后我按照规范从这个How to delete items from a dictionary while iterating over it?如何删除字典元素在for循环中

循环执行.keys

b = {'a':1, 'b' : 2} 
for k in b.keys(): 
    if b[k] == 1: 
     del b[k] 

结果:

Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration 
b 
{'b': 2} 

类似地,上循环.items()

b = {'a':1, 'b' : 2} 
for k, v in b.items(): 
    if v == 1: 
     del b[k] 

Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration 
b 
{'b': 2} 

循环后,它返回正确的结果,但也提出RuntimeError,我该如何解决它?

回答

3

你改变ddel d[k]所以遍历它.keys.values没有什么区别,你改变底层迭代器,所以它抱怨。

你既可以使.keyslist,与list(b),或.items,与list(b.items()),实质上将它们复制到一个新的迭代,不涉及字典你改变:

# list(b) would suffice instead of .keys 
for k in list(b.keys()): 
    if b[k] == 1: 
     del b[k] 

或者,使用词典理解:

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

过滤掉不需要的元素。

+0

'list'也是不必要的。因为v中的k应该是一样的。 – user312016

+0

你指的是什么? @ user312016 –

+0

噢,我错过了你的问题,我的例子不好,b代替v:for k in b。 – user312016

2

在迭代它时,无法删除dict中的元素。

最好的方法是使用一个dict理解:

b = {'a':1, 'b' : 2} 
b = {k: v for k, v in b.items() if v != 1} 

你也可以让你的dict的副本,在遍历它:

b = {'a':1, 'b' : 2} 
for k, v in dict(b).items(): 
    if v == 1: 
     del b[k] 

在这里,你迭代一个b的副本,同时修改原始的b,这就是它的工作原理:您永远不会从副本中删除元素。