dictionary size changed during iteration

Discussion in 'Python' started by Laszlo Nagy, Apr 20, 2011.

  1. Laszlo Nagy

    Laszlo Nagy Guest

    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
    Laszlo Nagy, Apr 20, 2011
    #1
    1. Advertising

  2. Laszlo Nagy

    Mel Guest

    Laszlo Nagy wrote:

    > 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.
    Mel, Apr 20, 2011
    #2
    1. Advertising

  3. Laszlo Nagy

    Mel Guest

    Mel wrote:
    > 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.
    Mel, Apr 20, 2011
    #3
  4. Laszlo Nagy

    John Nagle Guest

    On 4/20/2011 5:52 AM, Laszlo Nagy wrote:
    > 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
    John Nagle, Apr 22, 2011
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roman Suzi
    Replies:
    0
    Views:
    324
    Roman Suzi
    Jan 19, 2005
  2. Terry Reedy
    Replies:
    0
    Views:
    355
    Terry Reedy
    Jan 20, 2005
  3. robert
    Replies:
    29
    Views:
    1,042
    Raymond Hettinger
    Mar 14, 2006
  4. Jean-Paul Calderone
    Replies:
    0
    Views:
    359
    Jean-Paul Calderone
    Mar 13, 2006
  5. Robert Dailey
    Replies:
    6
    Views:
    374
    Terry Reedy
    Dec 9, 2008
Loading...

Share This Page