Reputation: 3662
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
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"
Upvotes: 1
Views: 560
Reputation: 964
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.
The easiest solution is to define k before the loop so that locals() doesn't change once the loop has started.
k = 0
l = locals()
for k in l:
print k,"points to",l[k],"\n"
Upvotes: 0
Reputation: 811
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. To avoid this error, you can use get
method and your statement will look like this then:
for k in l:
print k,"points to",l.get(k),"\n"
Upvotes: 0
Reputation: 88997
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.
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 - e.g: l = dict(locals())
. This way the original being updated won't cause problems.
Upvotes: 10