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