我希望在字典中弹出所有大值及其键,并保持最小值。这是我的程序的一部分
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
如何避免此错误?
答案 0 :(得分:9)
在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://hanbaobao2005.wordpress.com/2016/07/21/loop-a-dict-to-update-key/
答案 1 :(得分:8)
如果您正在寻找字典中的最小值,您可以这样做:
min(dictionary.values())
如果你不能使用min,你可以使用sorted:
sorted(dictionary.values())[0]
在旁注中,您遇到Runtime Error
的原因是在内部循环中您修改了外部循环所基于的迭代器。当pop
外部循环尚未到达的条目和外部迭代器到达它时,它会尝试访问已删除的元素,从而导致错误。
如果您尝试在Python 2.7(而不是3.x)上执行代码,实际上您将获得Key Error
。
如果要基于其迭代器在循环中修改 iterable ,则应使用deep copy。
答案 2 :(得分:5)
您可以使用copy.deepcopy制作原始字典的副本,在更改原始字典时循环复制。
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.
你的问题是在你正在改变的事情上重复。
答案 3 :(得分: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)
答案 4 :(得分:1)
以下是解决问题的一种方法:
以下是一个示例:
# 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()函数:我们不是按键排序,而是按值排序。
答案 5 :(得分:0)
当我现在读你的循环时,你只想保留单个最小元素,但不使用min
。所以与你的代码现在做的相反,检查是否value1 < minValueSoFar
,如果是,请将key1保持为minKeySoFar。然后在循环结束时(如Zayatzz建议的那样),执行dictionary.pop(minKeySoFar)
顺便说一句,我注意到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
答案 6 :(得分:0)
如果你想只保留具有最小值的键,我会先找到该项然后创建一个只包含它的新词典。如果你的词典是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)
答案 7 :(得分:0)
字典在迭代过程中更改大小的另一种方法:
this.form=this.formbuilder.group({
countryCode:[null,[Validators]]
)}
使用这种类型的代码时,最好小心!使用它,因为
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)
是在编译器第一次进入循环时计算的。因此,对字典所做的任何更改都不会影响当前循环内的过程。
答案 8 :(得分:0)
您可以创建一个包含要删除的值的列表,然后再运行一个 for 循环:
for entry in (listofkeystopop):
dictionary.pop(entry)