RuntimeError: dictionary changed size during iteration

Discussion in 'Python' started by Robert Dailey, Dec 8, 2008.

  1. I'm executing the following code:

    def CopyBoost( libraries ):
    pass

    def CopyEmotionFX( libraries ):
    pass


    def Copy( library, aliases ):
    pass

    stuff = vars()
    for key in stuff:
    print( key, '--', stuff[key] )



    I get the following error message:
    ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    Traceback (most recent call last):
    File "C:\IT\work\jewett\depends.py", line 12, in <module>
    for key in stuff:
    RuntimeError: dictionary changed size during iteration

    Why is this happening?
     
    Robert Dailey, Dec 8, 2008
    #1
    1. Advertising

  2. Robert Dailey

    Terry Reedy Guest

    Robert Dailey wrote:

    > stuff = vars()


    >>> vars() is globals()

    True

    > for key in stuff:


    You just changed globals, which is aliased as stuff.
    Stuff changes.

    > print( key, '--', stuff[key] )
    >
    >
    >
    > I get the following error message:
    > ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    > Traceback (most recent call last):
    > File "C:\IT\work\jewett\depends.py", line 12, in <module>
    > for key in stuff:
    > RuntimeError: dictionary changed size during iteration
    >
    > Why is this happening?
     
    Terry Reedy, Dec 9, 2008
    #2
    1. Advertising

  3. On Dec 8, 6:26 pm, Terry Reedy <> wrote:
    > Robert Dailey wrote:
    > > stuff = vars()

    >
    >  >>> vars() is globals()
    > True
    >
    > > for key in stuff:

    >
    > You just changed globals, which is aliased as stuff.
    > Stuff changes.
    >
    > >     print( key, '--', stuff[key] )

    >
    > > I get the following error message:
    > > ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    > > Traceback (most recent call last):
    > >   File "C:\IT\work\jewett\depends.py", line 12, in <module>
    > >     for key in stuff:
    > > RuntimeError: dictionary changed size during iteration

    >
    > > Why is this happening?

    >
    >


    How am I changing globals()? I'm simply iterating the keys in the
    dict. Can someone explain what is going on please?
     
    Robert Dailey, Dec 9, 2008
    #3
  4. On Mon, 08 Dec 2008 19:10:00 -0800, Robert Dailey wrote:

    > On Dec 8, 6:26 pm, Terry Reedy <> wrote:
    >> Robert Dailey wrote:
    >> > stuff = vars()

    >>
    >>  >>> vars() is globals()
    >> True
    >>
    >> > for key in stuff:

    >>
    >> You just changed globals, which is aliased as stuff. Stuff changes.
    >>
    >> >     print( key, '--', stuff[key] )

    >>
    >> > I get the following error message:
    >> > ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    >> > Traceback (most recent call last):
    >> >   File "C:\IT\work\jewett\depends.py", line 12, in <module>
    >> >     for key in stuff:
    >> > RuntimeError: dictionary changed size during iteration

    >>
    >> > Why is this happening?

    >>
    >>
    >>

    > How am I changing globals()? I'm simply iterating the keys in the dict.
    > Can someone explain what is going on please?


    You create an new name "key":

    for key in stuff

    I suppose you could do this:


    key = None
    stuff = vars()
    for key in stuff:


    but even better would be:

    for key in vars().copy():

    because that protects you from cases where globals() change inside the
    for loop.



    --
    Steven
     
    Steven D'Aprano, Dec 9, 2008
    #4
  5. Robert Dailey

    John Machin Guest

    On Dec 9, 3:00 pm, Steven D'Aprano
    <> wrote:
    > On Mon, 08 Dec 2008 19:10:00 -0800, Robert Dailey wrote:
    > > On Dec 8, 6:26 pm, Terry Reedy <> wrote:
    > >> Robert Dailey wrote:
    > >> > stuff = vars()

    >
    > >>  >>> vars() is globals()
    > >> True

    >
    > >> > for key in stuff:

    >
    > >> You just changed globals, which is aliased as stuff. Stuff changes.

    >
    > >> >     print( key, '--', stuff[key] )

    >
    > >> > I get the following error message:
    > >> > ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    > >> > Traceback (most recent call last):
    > >> >   File "C:\IT\work\jewett\depends.py", line 12, in <module>
    > >> >     for key in stuff:
    > >> > RuntimeError: dictionary changed size during iteration

    >
    > >> > Why is this happening?

    >
    > > How am I changing globals()? I'm simply iterating the keys in the dict.
    > > Can someone explain what is going on please?

    >
    > You create an new name "key":
    >
    > for key in stuff
    >
    > I suppose you could do this:
    >
    > key = None
    > stuff = vars()
    > for key in stuff:


    but both 'key' and 'stuff' will appear in the dict, possibly causing
    confusion; another reason why

    > even better would be:
    >
    > for key in vars().copy():
    >
    > because that protects you from cases where globals() change inside the
    > for loop.
     
    John Machin, Dec 9, 2008
    #5
  6. On Dec 8, 10:27 pm, John Machin <> wrote:
    > On Dec 9, 3:00 pm, Steven D'Aprano
    >
    >
    >
    > <> wrote:
    > > On Mon, 08 Dec 2008 19:10:00 -0800, Robert Dailey wrote:
    > > > On Dec 8, 6:26 pm, Terry Reedy <> wrote:
    > > >> Robert Dailey wrote:
    > > >> > stuff = vars()

    >
    > > >>  >>> vars() is globals()
    > > >> True

    >
    > > >> > for key in stuff:

    >
    > > >> You just changed globals, which is aliased as stuff. Stuff changes.

    >
    > > >> >     print( key, '--', stuff[key] )

    >
    > > >> > I get the following error message:
    > > >> > ('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
    > > >> > Traceback (most recent call last):
    > > >> >   File "C:\IT\work\jewett\depends.py", line 12, in <module>
    > > >> >     for key in stuff:
    > > >> > RuntimeError: dictionary changed size during iteration

    >
    > > >> > Why is this happening?

    >
    > > > How am I changing globals()? I'm simply iterating the keys in the dict.
    > > > Can someone explain what is going on please?

    >
    > > You create an new name "key":

    >
    > > for key in stuff

    >
    > > I suppose you could do this:

    >
    > > key = None
    > > stuff = vars()
    > > for key in stuff:

    >
    > but both 'key' and 'stuff' will appear in the dict, possibly causing
    > confusion; another reason why
    >
    > > even better would be:

    >
    > > for key in vars().copy():

    >
    > > because that protects you from cases where globals() change inside the
    > > for loop.

    >
    >


    When I do:

    for key in stuff.keys():


    It works! I wonder why .keys() makes a difference. It is using a
    'view', which is a new concept in Python 3.0 that I'm not totally
    familiar with yet.
     
    Robert Dailey, Dec 9, 2008
    #6
  7. Robert Dailey

    Terry Reedy Guest

    Robert Dailey wrote:

    > When I do:
    >
    > for key in stuff.keys():
    >
    >
    > It works! I wonder why .keys() makes a difference. It is using a
    > 'view', which is a new concept in Python 3.0 that I'm not totally
    > familiar with yet.


    Because stuff.keys() is evaluated *once* and the result is a separate
    object from stuff == globals(), so creating the new entry 'key' in
    globals == stuff does not change that new object.
     
    Terry Reedy, Dec 9, 2008
    #7
    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:
    333
    Roman Suzi
    Jan 19, 2005
  2. Terry Reedy
    Replies:
    0
    Views:
    372
    Terry Reedy
    Jan 20, 2005
  3. robert
    Replies:
    29
    Views:
    1,059
    Raymond Hettinger
    Mar 14, 2006
  4. Jean-Paul Calderone
    Replies:
    0
    Views:
    370
    Jean-Paul Calderone
    Mar 13, 2006
  5. Laszlo Nagy
    Replies:
    3
    Views:
    376
    John Nagle
    Apr 22, 2011
Loading...

Share This Page