I'll define a = [[1,1],[2,2],[3,3]]
a bit differently. Let's say:
b = [1,1]
c = [2,2]
d = [3,3]
a = [b,c,d]
This is the exact same thing as you have, we just gave the inner list names so that it is easier to follow later on.
One might call those names references, or pointers to memory locations. If you're not familiar with those terms, a way of looking at is "b
does not contain [1,1]
, it just knows where it is in the program's memory".
Ok, now at self.a[0] = self.a[1]
.
What this line does is it says to the program: "assign the first element of list a to be the same as the second one".
It does not say "copy the second element to the first one".
The difference is that both self.a[0]
and self.a[1]
point to the same array [2,2]
. In other words a = [c,c,d]
now.
self.a[1] = self.a[2]
does the same thing, but for different elements, so a = [c, d, d]
.
So far, everything is as you expect it.
The array equals [[2,2],[3,3],[3,3]]
when you print it, but the problem is that the [3,3]
here is the same array, it can just be accessed by two elements of self.a
.
Now let's tackle the self.a[2][0] += 1
part step by step:
- by calling
self.a[2]
we access the pointer to the array d = [3,3]
- following that logic, saying
self.a[2][0]
is the same as saying d[0]
- since we have incremented
d[0]
, and both self.a[1]
and self[2]
point to d
, both self.a[1][0]
and self.a[2][0]
have changed.
Another way of looking at it is that your code is equivalent to:
class A():
def __init__(self):
self.b = [1,1]
self.c = [2,2]
self.d = [3,3]
self.a = [self.b, self.c, self.d]
self.a[0] = self.c
self.a[1] = self.d
self.d[0] += 1
print(self.a)
aaa = A()
The array in self.a
is not an array that contains arrays, it's just an array that contains variables that know where those arrays are (i.e. pointers or references).