在迭代期间更新字典

时间:2016-04-26 04:38:59

标签: python dictionary

在更新单独的字典时是否可以迭代字典?我试图创建我的原始字典的副本并编辑该字典,但我仍然收到错误

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

我需要在每次循环时找到字典的最大值。然后我需要从字典中删除该项目,以便找到下一个最大的项目。

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

$(function() {
    $( "#inputFieldId" ).autocomplete({
        source: function( event, ui ) {
            alert("do your functions here");
            return false;
        }
    });
});

4 个答案:

答案 0 :(得分:0)

迭代dict的副本:

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])

答案 1 :(得分: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}
>>> 

答案 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

答案 3 :(得分: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])