Appending an empty list to a list does append previous list contents

Question:

Simple console sequence:

    >>> A=[]; B=[]
    >>> A.append(1)
    >>> A
    [1]
    >>> A=[]
    >>> A
    []
    >>> B.append(A)
    >>> B
    [[]]

so far so expected.
B ist now a list containing one element, which is an empty list.
A is an empty list.
Let’s continue:

    >>> A.append(1)
    >>> A
    [1]
    >>> A=[]
    >>> A
    []

A has the same value as first time. Now the surprise (to me at least):

    >>> B.append(A)
    >>> B
    [[1], []]
    >>>

Why ????
How and where ist the previous content of A, the 1, stored, and why is [1] pre(!!)pended to B instead of another empty list being appended ?

Asked By: Orla

||

Answers:

You’ve stumbled on pointers! What’s happening is that, each time you declare a new list using =[], a new object is created in memory. Each variable is only "pointing to" that location in memory.

So the sequence of what happened is that you created a list at location x01 and A was pointing at location x01. Then, you appended 1 to that list, so location x01 held an element "1". Then, you created a new list B at x02, which now holds a reference pointing to x01.

When you then overwrote A, you created a new list at x03 and set A to point there. However, B is still pointing at x02, which is still pointing at x01, which still holds a 1! Therefore, when you now append A to B, B is pointing at a location in memory (x02) which has two pointers: one at x01 and one at x03. x01 holds a 1 and x03 is empty.

The bottom line is, be cognizant of when you are creating a new object and when you are editing an existing object – editing an object will not create a new memory location, but creating a new object will. You can get some pretty unintuitive behavior with this if you’re not careful.

Answered By: David_Leber
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.