在回答一个特殊的问题时,我偶然发现了一个我无法解释的特殊问题。不幸的是,前两个Google搜索页面返回了一个SO页面,这也没有帮助。
问题代码
>>> 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正在发脾气,但是随后的执行很好,正如您在示例中看到的,当我第一次遍历字典时,它给出了运行时错误,但是下一次它没有抱怨。
知道怎么回事吗?
万一需要的话
>>> 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)
迭代字典时添加或删除字典项是错误的。因为
somehash
是一个defaultdict
,所以即使行中看起来是只读访问可能会添加一个新的密钥,从而导致遇到错误。
正如Sven所解释的,您遇到的错误是由于
defaultdict
的工作方式造成的。在defaultdict
中执行查找时,如果密钥不存在,则检索默认值(因此是名称)并将密钥添加到字典(使用默认值)。这是你的RuntimeError
的来源。您可以执行以下操作来避免此问题:
主要的区别在于
somehash.items()
返回一个(键,值)元组的列表,因此实际上是在该列表上迭代,而不是somehash
本身。这同样适用于.keys()
与.iterkeys()
。您正在生成1到1000之间的9999个(有点)随机整数,存储在
somedata
中,它用作somehash
的键,用于存储某些数据中数字的出现。作为} function which returns an empty list ,因此在迭代过程中正确地抛出了一个错误,正如*fasturtle*已经指出的那样。
maxkey=0
,这个键将永远不存在。在使用defaultdict时,when each key is encountered for the first time, an entry is automatically created using the ^{使用
get
方法安全地检索项。我看到您正在使用Python 2.7,它有一个名为
Counter
的新集合类,用于计算散列对象。使用Counter
应该比上面的代码快,并将代码缩减为:相关问题 更多 >
编程相关推荐