简体   繁体   English

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

[英]Strange runtime error while iterating a dictionary

I ran the this block of code and get errors like below: 我运行了这段代码,并得到如下错误:

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

The only thing I do is printing in the for loop at line 27 我唯一要做的就是在第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"

The reason for this is that you loop introduces a new local variable, k , which means that your dictionary of local variables is changed in the loop. 这样做的原因是,循环引入了一个新的局部变量k ,这意味着循环中将更改局部变量的字典。

The easiest solution (if you really need to do this, although it's a sign of a bad idea, generally) is to copy the dictionary - eg: l = dict(locals()) . 最简单的解决方案(如果确实需要这样做,虽然通常是个坏主意,但确实需要这样做)是复制字典-例如: l = dict(locals()) This way the original being updated won't cause problems. 这样,原始文件就不会引起问题。

The reason for the error is that Python thinks, since you access the dict by key, you could change the dict, which is restricted here. 发生错误的原因是Python认为,由于您通过键访问dict,因此可以更改dict,这在这里是受限制的。 To avoid this error, you can use get method and your statement will look like this then: 为避免此错误,可以使用get方法,然后您的语句将如下所示:

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

The reason for this is that you loop introduces a new local variable, k, which means that your dictionary of local variables is changed in the loop. 原因是您的循环引入了一个新的局部变量k,这意味着您的局部变量字典在循环中被更改。

The easiest solution is to define k before the loop so that locals() doesn't change once the loop has started. 最简单的解决方案是在循环之前定义k,以便一旦循环开始就不会更改locals()。

k = 0
l = locals()

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM