In Python, the code $a = [1] * 5$ evals to $[1, 1, 1, 1, 1]$; essentially five copies of the same object. Consider the following code:

matrix = [[0] * 5] * 5

It simply creates a $5 X 5$ matrix with all values defaulted to zero.

0matrix.svg

Now, if we simply change the element at $(0, 0)$ to $2$,

matrix[0][0] = 2

and plot the array:

0matrix.svg

It weirdly changes the whole [first] column to $2$!

Alright let’s unravel this. The line $[0] * 5$ creates five references to the object $0$. An object is just some data residing in some memory location. And a reference is a pointer to that object. In the above case, all five copies point to the same memory location (which contains an object $"0"$).

[0] x 5

[0] x 5

And $[[0] * 5] * 5$ just creates five references to that object (the internal list $[0, 0, 0, 0, 0]$).

[[0] x 5] x 5

[[0] x 5] x 5

As a consequence, mutating any one list affects all the lists.

matrix[0] is matrix[1] # compares if two objects are infact the same object
# True
matrix[0][0] is matrix[1][0]
# True

Now, consider the following case

vector = [0] * 5

0matrix.svg

Again, Python just creates five references to the same $”0”$, as seen above (& below).

Screenshot 2022-11-18 at 1.58.46 PM.png