[Tutor] Copying lists of lists

Hakan Nilsson hakan@netg.se
Tue, 10 Oct 2000 10:29:09 +0200 (CEST)


On Tue, 10 Oct 2000, Norman Charnley wrote:

> As the subject line says, I want to make a copy of a list of lists, but
> I've encountered a problem which I can't understand.
> 
> First the obvious:
> 
> >>> a=[1,2,3]
> >>> b=a[:]
> >>> b[0]=99
> >>> print a,b
> >>> [1, 2, 3] [99, 2, 3]
> 
> OK, so far, so good. But:
> 
> >>> a=[[1,2,3],[4,5,6],[7,8,9]]
> >>> b=a[:]
> >>> b[0][0]=99
> >>> print a
> [[99, 2, 3], [4, 5, 6], [7, 8, 9]]
> >>> print b
> [[99, 2, 3], [4, 5, 6], [7, 8, 9]]
> 
> i.e. a is reflecting the change made in b.
> 
> However, the following does work as I expected:
> >>> a=[[1,2,3],[4,5,6],[7,8,9]]
> >>> b=a[:]
> >>> b[0]=99
> >>> print a
> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
> >>> print b
> [99, [4, 5, 6], [7, 8, 9]]
> 
> Help, I'm a little confused, and I'd be grateful for an explanation. If
> this were C I'd think it was a pointer problem...!
> 
> Many thanks,
> 
> Norman

When you copy a by setting

b = a[:]

you get a copy of the first level only, since all items in the list a are
new listobjects, all referenses in b point to the same lists as in a.

When you do 

b[0] = 99

you set the first object in b to be a new object, thus not changing
anything that has to do with a, but when you do 

b[0][0] = 99

you change the first element of the first element, and since the first
element of a and b point at the same list, this is what happens.

What you should check out is the copy module, specifically copy.deepcopy,
that will do a full copy of everything in a.

/Hakan

-
 Hi! I'm a .signature virus!
 Copy me into your .signature file to help me spread!