I found a quirk in Python for matrices/nested lists that I would like to understand.
The thing I want to create is an initialized n by n matrix (n is a positive integer), meaning it has 0 everywhere. In Python I implement this as usual as a list with n entries, each entry being a list of length n with every entry being 0.
Let us implement (or at least seemingly implement) this in two ways for n=3.
n = 3
matrix1 = n*[n*[0]]
matrix2 = [[0 for j in range(n)] for i in range(n)]
print(f"matrix1 initialized as `n*[n*[0]]` is:\n{matrix1}")
print(f"matrix2 initialized as `[[0 for j in range(n)] for i in range(n)]` is:\n{matrix2}")
The output reads
matrix1 initialized as `n*[n*[0]]` is:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
matrix2 initialized as `[[0 for j in range(n)] for i in range(n)]` is:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Now see what happens in each case when I change some entries. In this case I am changing the second row (the row with the index 1) to have as its entries 1, 2, and 3, from left to right, which I do for both matrices.
matrix1[0][0], matrix1[0][1], matrix[0][2] = 1, 2, 3
matrix2[0][0], matrix2[0][1], matrix[0][2] = 1, 2, 3
print(f"matrix1 initialized as `n*[n*[0]]` is:\n{matrix1}")
print(f"matrix2 initialized as `[[0 for j in range(n)] for i in range(n)]` is:\n{matrix2}")
The output reads:
matrix1 initialized as `n*[n*[0]]` is:
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
matrix2 initialized as `[[0 for j in range(n)] for i in range(n)]` is:
[[0, 0, 0], [1, 2, 3], [0, 0, 0]]
The matrix2 output is what I expected to be the output of matrix1 as well, but it's not. Why is this the case?