List of lists surprising behaviour

bart.c bartc at freeuk.com
Fri Jun 18 11:40:35 EDT 2010


"Steven D'Aprano" <steve at REMOVE-THIS-cybersource.com.au> wrote in message
news:4c1b8ac6$0$14148$c3e8da3 at news.astraweb.com...
> On Fri, 18 Jun 2010 12:07:38 +0100, bart.c wrote:
>
>> (Although I have an issue with the way that that append works. I tried
>> it in another, simpler language (which always does deep copies):
>>
>> L:=(1,2,3)
>> L append:= L
>> print L
>>
>> output:  (1,2,3,(1,2,3))
>>
>> which is exactly what I'd expect,
>> and not (1,2,3,(1,2,3,(1,2,3,...))) )
>
> I find that behaviour a big surprise. You asked to append the list L, not
> a copy of the list L. So why is this "simpler" language making a copy
> without being asked?
>
> If you asked for:
>
> L:=(1,2,3)
> M:=(0,1)
> M append:= L
>
> does it also append a copy of L instead of L?

It make a copy.

> If so, how do you append
> the original rather than wastefully making a copy?

I don't think it can, without perhaps doing something with explicit
pointers.

> If L is huge, making a
> copy before appending will be slow, and potentially fail.

I don't know whether L append:=L requires 3 times the space of L, or 2
times, during the operation. But it should be doable using just twice the
space.

I suppose there are pros and cons to both approaches; copying all the time
at least avoids some of the odd effects and inconsistencies you get using
Python:

a1=[1,2,3]
a1.append(a1)

a2=[1,2,3]
b=[1,2,3]
a2.append(b)

a3=[1,2,3]
a3.append([1,2,3])

print ("a1 = ",a1)
print ("a2 = ",a2)
print ("a3 = ",a3)

Here, a1 ends up with a different result from a2, a3, even though the same
value is being appended to the same list of numbers in each case. And it 
might sometimes bite you in the arse as the OP demonstrated:

L=[1,2,3]
M=[0,1]
M.append(L)

print (M)     # output: [0, 1, [1, 2, 3]]

L[1]=31416

print (M)     # output: [0, 1, [1, 31416, 3]], yikes!

-- 
Bartc





More information about the Python-list mailing list