dictionary size changed during iteration

L

Laszlo Nagy

Given this iterator:

class SomeIterableObject(object):
....
....

def __iter__(self):
ukeys = self.updates.keys()
for key in ukeys:
if self.updates.has_key(key):
yield self.updates[key]
for rec in self.inserts:
yield rec
....
....

How can I get this exception:

RuntimeError: dictionary changed size during iteration


It is true that self.updates is being changed during the iteration. But
I have created the "ukeys" variable solely to prevent this kind of
error. Here is a proof of correctness:
d = {1:1,2:2}
k = d.keys()
del d[1]
k [1, 2]
k is d.keys()
False

So what is wrong with this iterator? Why am I getting this error message?

Thanks,

Laszlo
 
M

Mel

Laszlo said:
Given this iterator:

class SomeIterableObject(object):
....
....

def __iter__(self):
ukeys = self.updates.keys()
for key in ukeys:
if self.updates.has_key(key):
yield self.updates[key]
for rec in self.inserts:
yield rec
....
....

How can I get this exception:

RuntimeError: dictionary changed size during iteration


It is true that self.updates is being changed during the iteration. But
I have created the "ukeys" variable solely to prevent this kind of
error. Here is a proof of correctness:
d = {1:1,2:2}
k = d.keys()
del d[1]
k [1, 2]
k is d.keys()
False

So what is wrong with this iterator? Why am I getting this error message?

`ukeys` isn't a different dictionary from `self.updates.keys` I'ts merely
another name referring to the same dict object. I think

ukeys = dict (self.updates.keys)

would do what you want.

Mel.
 
M

Mel

Mel said:
Laszlo Nagy wrote:
`ukeys` isn't a different dictionary from `self.updates.keys` I'ts merely
another name referring to the same dict object. I think

ukeys = dict (self.updates.keys)

would do what you want.

Sorry. Belay that. Thought I'd had enough coffee.

Mel.
 
J

John Nagle

Given this iterator:

class SomeIterableObject(object):
....
....

def __iter__(self):
ukeys = self.updates.keys()
for key in ukeys:
if self.updates.has_key(key):
yield self.updates[key]
for rec in self.inserts:
yield rec
....
....

How can I get this exception:

RuntimeError: dictionary changed size during iteration


It is true that self.updates is being changed during the iteration. But
I have created the "ukeys" variable solely to prevent this kind of
error. Here is a proof of correctness:

I think we need to see some more code here.

Also, what version of Python are you running?

http://docs.python.org/library/stdtypes.html

says "keys()
Return a copy of the dictionary’s list of keys."

So "ukeys" should be a unique list, not some part of
self.updates or a generator.

At least in Python 2.6, keys() does return a unique list. Each
call to "keys()" returns a new list object unconnected to the
dictionary from which the keys were extracted. But someone may
have decided in a later version to return a generator, as
an optimization. Did that happen?

John Nagle
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top