Bug with lists of pairs of lists and append()

G

Gabriel Zachmann

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.
 
P

Paul Hankin

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))]
 
J

Jason M Barnes

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.

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
 
G

Gabriel Zachmann

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
______________________________________________________________
 
G

Gabriel Zachmann

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
______________________________________________________________
 
G

Gabriel Zachmann

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
______________________________________________________________
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top