2016-04-26 125 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