![](/img/trans.png)
[英]RuntimeError: dictionary changed size during iteration - how to solve?
[英]How to solve dictionary changed size during iteration error?
我想在字典中彈出所有大值及其鍵,並保持最小。 這是我的程序的一部分
for key,value in dictionary.items():
for key1, value1 in dictionary.items():
if key1!= key and value > value1:
dictionary.pop(key)
print (dictionary)
這導致
RuntimeError: dictionary changed size during iteration
我怎樣才能避免這個錯誤?
在 Python3 中,嘗試
for key in list(dict.keys()):
if condition:
matched
del dict[key]
循環 dict 以更新其密鑰時,還有一件事應該小心:
代碼1:
keyPrefix = ‘keyA’
for key, value in Dict.items():
newkey = ‘/’.join([keyPrefix, key])
Dict[newkey] = Dict.pop(key)
代碼2:
keyPrefix = ‘keyA’
for key, value in Dict.keys():
newkey = ‘/’.join([keyPrefix, key])
Dict[newkey] = Dict.pop(key)
code1/code2 的結果是:
{‘keyA/keyA/keyB’ : ”, ‘keyA/keyA/keyA’: ”}
我解決這個意外結果的方法:
Dict = {‘/’.join([keyPrefix, key]): value for key, value in Dict.items()}
鏈接: https : //blog.gainskills.top/2016/07/21/loop-a-dict-to-update-key/
如果您正在尋找字典中的最小值,您可以這樣做:
min(dictionary.values())
如果不能使用 min,則可以使用 sorted:
sorted(dictionary.values())[0]
附帶說明一下,您遇到Runtime Error
的原因是在內循環中修改了外循環所基於的迭代器。 當您pop
外部循環尚未到達的條目並且外部迭代器到達它時,它會嘗試訪問已刪除的元素,從而導致錯誤。
如果您嘗試在 Python 2.7(而不是 3.x)上執行您的代碼,實際上您會得到一個Key Error
。
如果要根據迭代器修改循環內的可迭代對象,則應使用它的深層副本。
您可以使用copy.deepcopy制作原始 dict 的副本,在更改原始副本的同時循環復制副本。
from copy import deepcopy
d=dict()
for i in range(5):
d[i]=str(i)
k=deepcopy(d)
d[2]="22"
print(k[2])
#The result will be 2.
你的問題是迭代你正在改變的東西。
在循環過程中記錄鍵,然后在循環完成時執行 dictionary.pop(key) 。 像這樣:
for key,value in dictionary.items():
for key1, value1 in dictionary.items():
if key1!= key and value > value1:
storedvalue = key
dictionary.pop(key)
這是解決它的一種方法:
這是一個示例:
# A list of grades, not in any order
grades = dict(John=95,Amanda=89,Jake=91,Betty=97)
# students is a list of students, sorted from lowest to highest grade
students = sorted(grades, key=lambda k: grades[k])
print 'Grades from lowest to highest:'
for student in students:
print '{0} {1}'.format(grades[student], student)
lowest_student = students[0]
highest_student = students[-1]
print 'Lowest grade of {0} belongs to {1}'.format(grades[lowest_student], lowest_student)
print 'Highest grade of {0} belongs to {1}'.format(grades[highest_student], highest_student)
這里的秘訣在於 sorted() 函數:我們不是按鍵排序,而是按值排序。
當我現在閱讀您的循環時,您希望只保留一個最小的元素,但不使用min
。 因此,請執行與您的代碼現在相反的操作,檢查value1 < minValueSoFar
,如果是,則將 key1 保留為 minKeySoFar。 然后在循環結束時(如 Zayatzz 建議的那樣),做一個dictionary.pop(minKeySoFar)
key1!=key
說一句,我注意到key1!=key
測試是無關緊要的,並且假設一個相當長的列表在計算上效率低下。
minValueSoFar = 9999999; # or whatever
for key,value in dictionary.items():
if value < minValueSoFar:
minValueSoFar = value
minKeySoFar = key
dictionary.pop(minKeySoFar) # or whatever else you want to do with the result
如果您只想保留具有最小值的鍵,我會先找到該項目,然后創建一個僅包含它的新字典。 如果你的字典是d
,這樣的事情會在一行中完成:
d = dict((min(d.items(), key=lambda item: item[1]),))
這不僅可以避免在迭代時更新字典的任何問題,而且可能比刪除所有其他元素更快。
如果您出於某種原因必須就地進行修改,則以下方法會起作用,因為它會在修改字典之前復制所有鍵:
key_to_keep = min(d.items(), key=lambda item: item[1])[0]
for key in list(d):
if key != key_to_keep:
d.pop(key)
字典在迭代期間改變大小的替代解決方案:
for key,value in list(dictionary.items()):
for key1, value1 in list(dictionary.items()):
if key1!= key and value > value1:
dictionary.pop(key)
print (dictionary)
最好謹慎使用! 當使用這種類型的代碼時,因為
list(dictionary.items())
在編譯器第一次進入循環時計算的。 因此,對字典所做的任何更改都不會影響當前循環內的進程。
您可以使用要刪除的值創建一個列表,然后再運行一個 for 循環:
for entry in (listofkeystopop):
dictionary.pop(entry)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.