首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RuntimeError:字典在迭代期间更改了大小-在默认字典上使用iteritems进行迭代期间

RuntimeError:字典在迭代期间更改了大小-在默认字典上使用iteritems进行迭代期间
EN

Stack Overflow用户
提问于 2012-01-07 02:46:07
回答 3查看 8.2K关注 0票数 5

在这里回答一个特定的问题时,我偶然发现了一个我无法解释的特殊问题。不幸的是,前两个谷歌搜索页面返回了一个SO页面,这也没有什么帮助。

问题代码

代码语言:javascript
复制
>>> somedata=[random.randint(1,1000) for i in xrange(1,10000)]
>>> somehash=collections.defaultdict(int)
>>> for d in somedata:
    somehash[d]+=1      
>>> maxkey=0
>>> for k,v in somehash.iteritems():
    if somehash[maxkey] > v:
        maxkey=k            

Traceback (most recent call last):
  File "<pyshell#700>", line 1, in <module>
    for k,v in somehash.iteritems():
RuntimeError: dictionary changed size during iteration
>>> for k,v in somehash.iteritems():
    if somehash[maxkey] > v:
        maxkey=k
>>>

由于一些奇怪的原因,当我第一次迭代字典时,Python创建了tantrums,但随后的执行都很好,就像你在示例中看到的那样,第一次迭代字典时,它给出了运行时错误,但下一次它没有错误。

你知道可能出了什么问题吗?

以防万一需要的话

代码语言:javascript
复制
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=0, releaselevel='final', serial=0)
>>> sys.version
'2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)]'

OS: Microsoft Windows [Version 6.1.7601] (Windows 7)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-07 02:50:50

在字典上迭代时添加或删除字典中的条目是错误的。由于somehash是一个defaultdict,所以即使是看似只读的访问也是如此

代码语言:javascript
复制
if somehash[maxkey] > k:

可能会添加一个新的键--导致您遇到的错误。

票数 12
EN

Stack Overflow用户

发布于 2013-04-10 00:38:39

正如斯文解释的那样,你遇到的错误是由于defaultdict的工作方式造成的。在defaultdict中执行查找时,如果键不存在,则检索默认值(因此而得名),并将键添加到字典中(使用默认值)。这是您的RuntimeError的来源。

您可以执行以下操作来避免此问题:

代码语言:javascript
复制
for k, v in somehash.items():
    if somehash[maxkey] > v:
        maxkey = k

主要区别在于,somehash.items()返回一个(键、值)元组的列表,因此您实际上是在遍历该列表,而不是somehash本身。.keys().iterkeys()的情况也是如此。

票数 4
EN

Stack Overflow用户

发布于 2013-08-27 20:09:34

您将生成9999个(某种程度上)介于1和1000之间的随机整数,这些整数存储在用作somehash键的somedata中,以存储这些数字在某些数据中的出现情况。

作为maxkey=0,这个键永远不会存在。由于您使用的是缺省值 ,因此在迭代过程中正确地抛出了一个错误,正如“快速海龟”已经指出的那样。

使用get方法可以安全地检索项。

代码语言:javascript
复制
import random
import collections

somedata=[random.randint(1,1000) for i in xrange(1,10000)]
somehash=collections.defaultdict(int)
for d in somedata:
   somehash[d]+=1 

maxkey=0
for k,v in somehash.iteritems():
   if somehash.get(maxkey) > v:
       maxkey=k 
       print k,v  

我看到您使用的是Python2.7,它有一个名为Counter的新集合类,用于计算可哈希对象。使用Counter应该比上面的代码更快,并将您的代码减少为:

代码语言:javascript
复制
somedata=[random.randint(1,1000) for i in xrange(1,10000)]
somehash=collections.Counter(somedata)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8762819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档