strange behaviour with remove

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Panard

    strange behaviour with remove

    Hi!

    Can anyone explain this to me :
    $ cat test.py
    l = [ 1, 2, 3 ]
    d = { 'list' : l }

    for x in l :
    print "rm", x
    d[ 'list' ].remove( x )
    print "l =", l

    print d

    $ python test.py
    rm 1
    l = [2, 3]
    rm 3
    l = [2]
    {'list': [2]}


    Why 2 isn't removed ? and why l is changing during the loop ??
    Am I missing something ?

    My python is 2.3.4

    Thanks

    --
    Panard
  • Panard

    #2
    Re: strange behaviour with remove

    Ok, I reply to myself, it's working when you add, line 3
    l = [ i for i in l ]

    I think the reason is that when you do a remove on d[ 'list' ] it will also
    do a remove on l, because, I think, l in the dictionnary is only a
    reference...


    Panard wrote:
    [color=blue]
    > Hi!
    >
    > Can anyone explain this to me :
    > $ cat test.py
    > l = [ 1, 2, 3 ]
    > d = { 'list' : l }
    >
    > for x in l :
    > print "rm", x
    > d[ 'list' ].remove( x )
    > print "l =", l
    >
    > print d
    >
    > $ python test.py
    > rm 1
    > l = [2, 3]
    > rm 3
    > l = [2]
    > {'list': [2]}
    >
    >
    > Why 2 isn't removed ? and why l is changing during the loop ??
    > Am I missing something ?
    >
    > My python is 2.3.4
    >
    > Thanks
    >[/color]

    --
    Panard

    Comment

    • Reinhold Birkenfeld

      #3
      Re: strange behaviour with remove

      Panard wrote:[color=blue]
      > Ok, I reply to myself, it's working when you add, line 3
      > l = [ i for i in l ]
      >
      > I think the reason is that when you do a remove on d[ 'list' ] it will also
      > do a remove on l, because, I think, l in the dictionnary is only a
      > reference...[/color]

      You're partially right. The list referenced to by d['list'] is the same
      object as the list referenced to by l (to verify this, do a "print
      d['list'] is l"). The main reason that your loop does not work is that
      it modifying a list you are iterating over leads to undefined behavior.

      In your solution above, you are assigning a new list to the name "l",
      iterate over this list, and remove from the original list which is now
      only referenced by d['list']. This is the common solution for the
      problem, although there is an easier way to copy a list:

      l = l[:]

      Reinhold

      --
      Wenn eine Linuxdistributi on so wenig brauchbare Software wie Windows
      mitbrächte, wäre das bedauerlich. Was bei Windows der Umfang eines
      "kompletten Betriebssystems " ist, nennt man bei Linux eine Rescuedisk.
      -- David Kastrup in de.comp.os.unix .linux.misc

      Comment

      Working...