Bug with lists of pairs of lists and append()

Discussion in 'Python' started by Gabriel Zachmann, Sep 28, 2007.

  1. Well,

    could some kind soul please explain to me why the following trivial code is
    misbehaving?

    #!/usr/bin/python

    lst = [ 0, 1, 2 ]

    s = []

    l = [ lst[0] ]
    r = lst[1:]
    while r:
    x = (l,r)
    print x
    s.append( x )

    l.append( r.pop(0) )

    print s



    The output I get is:

    ([0], [1, 2])
    ([0, 1], [2])
    [([0, 1, 2], []), ([0, 1, 2], [])]

    and the error is in the last line: the two pairs in the outer list are
    identical and they should be as the pairs on the first and the 2nd line,
    respectively!

    I think I'm going nuts -- for the life of me I don't see what's going on ...
    (I've been tracking down a bug in my larger python script, and the cause
    seems to boil down to the above snippet.)

    Thanks a lot in advance for any insights, etc.

    Best regards,
    Gabriel.
     
    Gabriel Zachmann, Sep 28, 2007
    #1
    1. Advertising

  2. Gabriel Zachmann

    Paul Hankin Guest

    On Sep 28, 11:25 pm, Gabriel Zachmann <-
    clausthal.de> wrote:
    > could some kind soul please explain to me why the following trivial code is
    > misbehaving?
    >
    > lst = [ 0, 1, 2 ]
    > s = []
    > l = [ lst[0] ]
    > r = lst[1:]
    > while r:
    > x = (l,r)
    > print x
    > s.append( x )
    > l.append( r.pop(0) )
    > print s


    What TeroV said - you need to copy the lists into s otherwise they'll
    still mutate when you pop or append to them.
    Try putting an extra "print s" after the s.append(x) line, and you'll
    find that s changes between there and the final print statement
    outside the loop.

    Here's code that works:
    s, l, r = [], [0], [1, 2]
    while r:
    x = (list(l), list(r))
    print x
    s.append(x)
    l.append(r.pop(0))
    print s

    I'm using list(l) to copy the list, Tero uses l[:], but the idea is
    the same.

    But do you just want all proper partitions of lst? Then this is much
    simpler:
    lst = [0, 1, 2]
    s = [(lst[:i], lst[i:]) for i in range(1, len(lst))]

    --
    Paul Hankin
     
    Paul Hankin, Sep 29, 2007
    #2
    1. Advertising

  3. On 9/28/07, Gabriel Zachmann <-clausthal.de> wrote:
    > Well,
    >
    > could some kind soul please explain to me why the following trivial code is
    > misbehaving?
    >
    > #!/usr/bin/python
    >
    > lst = [ 0, 1, 2 ]
    >
    > s = []
    >
    > l = [ lst[0] ]
    > r = lst[1:]
    > while r:
    > x = (l,r)
    > print x
    > s.append( x )
    >
    > l.append( r.pop(0) )
    >
    > print s
    >
    >
    >
    > The output I get is:
    >
    > ([0], [1, 2])
    > ([0, 1], [2])
    > [([0, 1, 2], []), ([0, 1, 2], [])]
    >
    > and the error is in the last line: the two pairs in the outer list are
    > identical and they should be as the pairs on the first and the 2nd line,
    > respectively!
    >
    > I think I'm going nuts -- for the life of me I don't see what's going on ...
    > (I've been tracking down a bug in my larger python script, and the cause
    > seems to boil down to the above snippet.)
    >
    > Thanks a lot in advance for any insights, etc.
    >
    > Best regards,
    > Gabriel.
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >


    If you're familiar with C or C++, think of s as holding a pointer to x
    which in turn holds a pointer to l and r, so when you change l or r, x
    (and s indirectly) is still pointing to the same lists which by the
    end of your loop have changed to r=[] and l=[0,1,2].

    BTW: It's not really "misbehaving." It's doing exactly what you're
    telling it to do ;-)

    Jason
     
    Jason M Barnes, Sep 29, 2007
    #3
  4. > I'm using list(l) to copy the list, Tero uses l[:], but the idea is
    > the same.
    >


    Thanks a lot for your response and the hint.

    > But do you just want all proper partitions of lst? Then this is much
    > simpler:
    > lst = [0, 1, 2]
    > s = [(lst[:i], lst[i:]) for i in range(1, len(lst))]



    Ah, thanks a lot for that nice line of code!
    Python keeps astonishing me ;-)

    Cheers,
    Gabriel.

    --
    ______________________________________________________________
    Life is so constructed that the event does not, cannot,
    will not match the expectation. (Charlotte Bronte)
    ______________________________________________________________
    zach in.tu-clausthal.de __@/' www.gabrielzachmann.org
    ______________________________________________________________
     
    Gabriel Zachmann, Oct 1, 2007
    #4

  5. > If you're familiar with C or C++, think of s as holding a pointer to x
    > which in turn holds a pointer to l and r, so when you change l or r, x
    > (and s indirectly) is still pointing to the same lists which by the


    AH - thanks a million -- that makes it crystal clear!
    [Python's apparent simplicity keeps making me forget that everything is
    a pointer ...]

    > BTW: It's not really "misbehaving." It's doing exactly what you're
    > telling it to do ;-)


    i had a feeling ... ;-)

    Cheers,
    Gabriel.

    --
    ______________________________________________________________
    Life is so constructed that the event does not, cannot,
    will not match the expectation. (Charlotte Bronte)
    ______________________________________________________________
    zach in.tu-clausthal.de __@/' www.gabrielzachmann.org
    ______________________________________________________________
     
    Gabriel Zachmann, Oct 1, 2007
    #5

  6. > x = (list(l), list(r))


    BTW: I prefer this syntax, because it makes the copy explicit, while
    l[:] seems to me more "implicit" ...

    Best regards,
    Gabriel.

    --
    ______________________________________________________________
    Life is so constructed that the event does not, cannot,
    will not match the expectation. (Charlotte Bronte)
    ______________________________________________________________
    zach in.tu-clausthal.de __@/' www.gabrielzachmann.org
    ______________________________________________________________
     
    Gabriel Zachmann, Oct 1, 2007
    #6
    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. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    410
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  2. Piotr Filip Mieszkowski

    Pairs, lists and a recursive type

    Piotr Filip Mieszkowski, Oct 13, 2005, in forum: C++
    Replies:
    4
    Views:
    398
    Piotr Filip Mieszkowski
    Oct 19, 2005
  3. rhXX
    Replies:
    7
    Views:
    231
    Terry Reedy
    Jun 7, 2007
  4. HYRY
    Replies:
    10
    Views:
    608
    Bruno Desthuilliers
    Sep 26, 2007
  5. Gabriel Zachmann

    Bug with lists of pairs of lists and append()

    Gabriel Zachmann, Sep 28, 2007, in forum: Python
    Replies:
    2
    Views:
    235
    Gabriel Zachmann
    Oct 1, 2007
Loading...

Share This Page