modify dictionary while iterating

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • s99999999s2003@yahoo.com

    #1

    modify dictionary while iterating

    hi
    I wish to pop/del some items out of dictionary while iterating over it.
    a = { 'a':1, 'b':2 }
    for k, v in a.iteritems():
    if v==2:
    del a[k]

    the output say RuntimeError: dictionary changed size during iteration
    how can i suppress this message in an actual script and still get the
    final value of the dict?
    is it something like try/except/else statment?
    try:
    for v,k in a.iteritems():
    if v==something:
    del a[k]
    except RuntimeError:
    < don't know what to do here>
    else:
    < should i include this part ? >

    what other ways can i do this ? thanks for any help.

  • Peter Otten

    #2
    Re: modify dictionary while iterating

    s99999999s2003@ yahoo.com wrote:
    [color=blue]
    > hi
    > I wish to pop/del some items out of dictionary while iterating over it.
    > a = { 'a':1, 'b':2 }
    > for k, v in a.iteritems():
    > if v==2:
    > del a[k]
    >
    > the output say RuntimeError: dictionary changed size during iteration
    > how can i suppress this message in an actual script and still get the
    > final value of the dict?
    > is it something like try/except/else statment?
    > try:
    > for v,k in a.iteritems():
    > if v==something:
    > del a[k]
    > except RuntimeError:
    > < don't know what to do here>
    > else:
    > < should i include this part ? >
    >
    > what other ways can i do this ? thanks for any help.[/color]

    If you expect to delete only a few items:
    [color=blue][color=green][color=darkred]
    >>> a = dict(a=1, b=2, c=3, d=2)
    >>> delenda = [k for k, v in a.iteritems() if v == 2]
    >>> for k in delenda:[/color][/color][/color]
    .... del a[k]
    ....[color=blue][color=green][color=darkred]
    >>> a[/color][/color][/color]
    {'a': 1, 'c': 3}

    If you expect to delete most items:
    [color=blue][color=green][color=darkred]
    >>> a = dict(a=1, b=2, c=3, d=2)
    >>> a = dict((k, v) for k, v in a.iteritems() if v != 2)
    >>> a[/color][/color][/color]
    {'a': 1, 'c': 3}

    or (if rebinding a is not an option)
    [color=blue][color=green][color=darkred]
    >>> a = dict(a=1, b=2, c=3, d=2)
    >>> for k, v in a.items():[/color][/color][/color]
    .... if v == 2:
    .... del a[k]
    ....[color=blue][color=green][color=darkred]
    >>> a[/color][/color][/color]
    {'a': 1, 'c': 3}

    Peter

    Comment

    • Ben Finney

      #3
      Re: modify dictionary while iterating

      s99999999s2003@ yahoo.com wrote:[color=blue]
      > I wish to pop/del some items out of dictionary while iterating over
      > it.[/color]

      Iterate over a copy.

      a_orig = { 'a': 1, 'b': 2 }
      a = dict(a_orig)
      for k, v in a_orig.iteritem s():
      if v == 2:
      del a[k]

      --
      \ "I know the guy who writes all those bumper stickers. He hates |
      `\ New York." -- Steven Wright |
      _o__) |
      Ben Finney

      Comment

      • Fuzzyman

        #4
        Re: modify dictionary while iterating

        Iterate over the keys.... ( for entry in adict.keys(): )

        All the best,

        Fuzzy
        http://www.voidspace.org.uk/python/index.shtml

        Comment

        • skip@pobox.com

          #5
          Re: modify dictionary while iterating

          >> I wish to pop/del some items out of dictionary while iterating over[color=blue][color=green]
          >> it.[/color][/color]

          Ben> Iterate over a copy.

          Ben> a_orig = { 'a': 1, 'b': 2 }
          Ben> a = dict(a_orig)
          Ben> for k, v in a_orig.iteritem s():
          Ben> if v == 2:
          Ben> del a[k]

          Or iterate over just a copy of the keys:

          for k in a_orig.keys():
          if a_orig[k] == 2:
          del a_orig[k]

          Skip

          Comment

          • François Pinard

            #6
            Re: modify dictionary while iterating

            [s99999999s2003@ yahoo.com]
            [color=blue]
            >I wish to pop/del some items out of dictionary while iterating over it.[/color]
            [color=blue]
            >a = { 'a':1, 'b':2 }
            >for k, v in a.iteritems():
            > if v==2:
            > del a[k][/color]

            A simple change would be using "items()" instead of "iteritems( )".

            Or else, you may prefer to loop over keys, and retrieve values, either:

            for k in a.keys():
            if a[k] == 2:
            del a[k]

            or:

            for k in set(a):
            if a[k] == 2:
            del a[k]

            But in no way, you may directly iterate over the original dictionary
            while altering its keys, this is explicitly forbidden in Python.

            --
            François Pinard http://pinard.progiciels-bpi.ca

            Comment

            Working...