迭代字典时出现奇怪的运行时错误

时间:2013-01-03 17:30:06

标签: python runtime-error

我运行了这段代码并得到如下错误:

Traceback (most recent call last):
  File "urllister.py", line 26, in <module>
    for k in l: print k,"points to",l[k],"\n"
RuntimeError: dictionary changed size during iteration

我唯一要做的就是在第27行的for循环中打印

from sgmllib import SGMLParser

class URLLister(SGMLParser):
    def reset(self):
        SGMLParser.reset(self)
        self.data = []
    def start_a(self, attrs):
        href = [v for k , v in attrs if k == 'href']
        if href:
            self.data.extend(href)

if __name__ == '__main__':
    import urllib
    sock = urllib.urlopen("http://diveintopython.org")

    parser = URLLister()
    html = sock.read()

    parser.feed(html)

    sock.close()
    parser.close()
    for url in parser.data: print url
    l = locals()

    for k in l:
        print k,"points to",l[k],"\n"

3 个答案:

答案 0 :(得分:10)

这样做的原因是你循环引入了一个新的局部变量k,这意味着你的局部变量字典在循环中被改变了。

最简单的解决方案(如果你真的需要这样做,虽然这通常是一个坏主意的标志)是复制字典 - 例如:l = dict(locals())。这样,正在更新的原件不会导致问题。

答案 1 :(得分:0)

错误的原因是Python认为,因为你通过密钥访问dict,你可以改变dict,这是受限制的。要避免此错误,您可以使用get方法,然后您的语句将如下所示:

for k in l:
    print k,"points to",l.get(k),"\n"

答案 2 :(得分:0)

原因是你循环引入了一个新的局部变量k,这意味着你的局部变量字典在循环中被改变了。

最简单的解决方案是在循环之前定义k,以便一旦循环开始,locals()就不会改变。

k = 0
l = locals()

for k in l:
    print k,"points to",l[k],"\n"