2016-04-26 59 views
1

在更新单独的字典时是否可以遍历字典?我试图创建我原来的字典的副本,并编辑之一,但我仍然收到错误迭代期间更新字典

d = {30:3, 54:5, 16:2} 
r = d 
for k,v in d.items(): 
    biggest = max(d,key = d.get) 
    del(r[biggest]) 

我需要找到各个它遍历时间字典的最大价值。然后,我需要从字典中删除该项目,以便找到下一个最大的项目。

运行此代码时出现的错误如下。

Traceback (most recent call last): 
    File "<pyshell#7>", line 1, in <module> 
    for k,v in d.items(): 
RuntimeError: dictionary changed size during iteration 
+2

什么是这背后的目的是什么?最后,它会导致只是一个空的字典... – khlr

+0

你有没有试过建立一些东西,你知道你将使用的每种类型的电路板需要多长时间。问题是,因为木材来自8英尺的碎片,所以你总是会留下剩余的木材,这些木材太短而无法做任何事情。这可能会导致您购买太少的电路板。该计划将考虑所有这些因素,并告诉您需要购买多少块主板。 – DakotaDickey44

回答

0

你实际上是迭代因为r = d不会创建新的字典,所以在相同的字典中。 r只是对同一个词典的另一个参考。您可以检查对象身份确认:

>>> r = d 
>>> r is d 
True 

请参阅有关对象身份的更多讨论:

"is" operator behaves unexpectedly with integers

所以,做正确的事情是先创建a copy of the dictionary和然后改变它:

>>> r = d.copy() 
>>> r is d 
False 

和迭代:

for k,v in d.items(): 
    biggest = max(d,key = d.get) 
    del(r[biggest]) 

所以,从你的代码中,我们只需要改变一行:

d = {30:3, 54:5, 16:2} 
r = d.copy() // changed: use copy here 
for k,v in d.items(): 
    biggest = max(d,key = d.get) 
    del(r[biggest]) 
0

迭代的字典的副本:

d = {30:3, 54:5, 16:2} 
r = d 
for k,v in dict(d).items(): 
    biggest = max(d,key = d.get) 
    del(r[biggest]) 
0

的问题是,当你在该行r = d使用=,然后r是不是一个新的对象。这是相同的d。我的意思是他们是指单一词典:

>>> x = {'a':1, 'b':2} 
>>> y = x 
>>> x 
{'a': 1, 'b': 2} 
>>> y 
{'a': 1, 'b': 2} 
>>> x is y 
True 

所以,如果你改变其中的一个,其他的也可能发生变化:

>>> y['c']=3 
>>> y 
{'a': 1, 'c': 3, 'b': 2} 
>>> x 
{'a': 1, 'c': 3, 'b': 2} 

使用id()方法,你可以检查,如果他们指的是不同的在内存或没有地方:

>>> id(y) 
44703816L 
>>> id(x) 
44703816L 
>>> 

所以,你需要使用copy()方法而不是=

>>> import copy 
>>> z = copy.copy(x) 
>>> z 
{'a': 1, 'c': 3, 'b': 2} 
>>> x 
{'a': 1, 'c': 3, 'b': 2} 
>>> z is x 
False 
>>> 

导致改变其中之一,不改变其他:

>>> z 
{'a': 1, 'c': 3, 'b': 2} 
>>> x 
{'a': 1, 'c': 3, 'b': 2} 
>>> z['d']=4 
>>> z 
{'a': 1, 'c': 3, 'b': 2, 'd': 4} 
>>> x 
{'a': 1, 'c': 3, 'b': 2} 
>>> 
0

正如其他人所指出的那样,你不能在迭代彻底改变它的字典的大小。 @ user312016还指出,您可以遍历副本并修改原始内容。

我不知道目的是什么,但这样你就不必找在每次迭代最大这段代码将从最大值到最小的项目进行排序:

d = {30:3, 54:5, 16:2} 
d_ = sorted(d.items(), key=lambda x: x[1], reverse=True) 

for k, v in d_: 
    print(k, v) 

54, 5 
30, 3 
16, 2