When trying to change one value in a matrix, python will change all items of that column with the desired value, despite the fact I am only trying to change one. But this only happens when all rows are identical.
Example:
def print_matrix(matrix: list[list], dlm: str) -> None:
for row in matrix:
for col in row:
print(col, end = dlm)
print()
one_row = list(range(4))
test_matrix = []
for i in range(5):
test_matrix.append(one_row)
test_matrix[0][0] = 5
sec_matrix =[
[0,1,2,3],
[0,1,2,3],
[0,1,2,3],
[0,1,2,4]
]
sec_matrix[0][0]=5
print_matrix(test_matrix, ' ')
print()
print_matrix(sec_matrix, ' ')
In the first matrix every 0 gets replaced with a 5, despite only referencing the first item of the first list.
In the second one it works the way I want it to, because the last list is slightly different.
Why is there a difference in the way test_matrix and sec_matrix are treated? Is this a bug, or intended?
Does python just think they are the same list because they look the same?
Or are they even the same to increase performance? Either way I don’t think it should happen.
I tried to update a matrix item on certain coordinates.
I expected only the desired item to be altered, instead every single one of that column got changed. Problem is fixed by not having identical rows.
>Solution :
The reason is when you write test_matrix.append(one_row) you are appending actually [0,1,2,3] 5 times to test_matrix, essentially, i.e the list will look like [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]. Here each list element is a list with [0,1,2,3] references to the same [0,1,2,3]. When you then modify this single [0,1,2,3] it is visible via all references to it. For debugging purposes, you can check it,
print(id(test_matrix[0]))
print(id(test_matrix[1]))
So you will see all are the same id, if you want to do it then you can do it like below- where test_matrix = [ list(range(4)) for n in range(5) ] will re-generate value each time
def print_matrix(matrix, dlm):
for row in matrix:
for col in row:
print(col, end = dlm)
print()
test_matrix = []
test_matrix = [ list(range(4)) for n in range(5) ] # re-generate and appending
test_matrix[0][0] = 7
sec_matrix =[
[0,1,2,3],
[0,1,2,3],
[0,1,2,3],
[0,1,2,4]
]
sec_matrix[0][0]=5
print_matrix(test_matrix, ' ')
print()
print_matrix(sec_matrix, ' ')
Output:
7 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3
5 1 2 3
0 1 2 3
0 1 2 3
0 1 2 4