Reputation: 152
Im trying to solve a coding problem where i have to generate some matrices, im new to python and i cant figure out why my matrix keeps getting changed to the latest matrix being generated. Here's the code i have so far:
def mirrorHorizontal(m):
l = list(m)
matrix_len = len(l)
for x in range(0,matrix_len):
temp = l[x][matrix_len-1]
l[x][matrix_len-1] = l[x][0]
l[x][0] = temp
return l
def mirrorVertical(m):
l = list(m)
matrix_len = len(l)
for x in range(0,matrix_len):
temp = l[0][x]
l[0][x] = l[matrix_len-1][x]
l[matrix_len-1][x] = temp
return l
def rotateMatrix(m):
l = list(m)
matrix_len = len(l)
rotated_matrix = []
for x in range(0,matrix_len):
rotated_row = []
for y in range(0, matrix_len):
rotated_row.append([(matrix_len-1) -y][y])
rotated_matrix.append(rotated_row)
return rotated_matrix
# Complete the formingMagicSquare function below.
def formingMagicSquare(s):
all_matrices = []
base_matrix = [[8,3,4],[1,5,9],[6,7,2]]
all_matrices.append(base_matrix)
print("all matrices after first append",all_matrices)
base_h_mirror = list(mirrorHorizontal(base_matrix))
print("horizontal_mirror",base_h_mirror)
all_matrices.append(base_h_mirror)
print("all matrices after first h mirror append",all_matrices)
base_v_mirror = list(mirrorVertical(base_matrix))
print("vertical_mirror",base_v_mirror)
all_matrices.append(base_v_mirror)
print("all matrices after first v mirror append",all_matrices)
#Same as vertical mirror of horizontal mirror
base_v_h_mirror = list(mirrorHorizontal(base_v_mirror))
all_matrices.append(base_h_mirror)
print("h_mirror added",all_matrices)
all_matrices.append(base_v_mirror)
print("h_mirror added",all_matrices)
all_matrices.append(base_v_h_mirror)
print("base_v_h_mirror added",all_matrices)
print("mirrored matrices= ",all_matrices)
matrix_len = len(all_matrices)
for x in range(0,matrix_len):
all_matrices.append(rotateMatrix(all_matrices[x]))
print(all_matrices)
formingMagicSquare()
The output , if you run it is something like:
all matrices after first append [[[8, 3, 4], [1, 5, 9], [6, 7, 2]]]
horizontal_mirror [[4, 3, 8], [9, 5, 1], [2, 7, 6]]
all matrices after first h mirror append
[
[[4, 3, 8], [9, 5, 1], [2, 7, 6]],
[[4, 3, 8], [9, 5, 1], [2, 7, 6]]
]
vertical_mirror [[2, 7, 6], [9, 5, 1], [4, 3, 8]]
all matrices after first v mirror append
[[[2, 7, 6], [9, 5, 1], [4, 3, 8]],
[[2, 7, 6], [9, 5, 1], [4, 3, 8]],
[[2, 7, 6], [9, 5, 1], [4, 3, 8]]]
h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
base_v_h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
mirrored matrices= [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
Why is my matrix being populated with the same matrix again and again? I converted the list in the functions i used by slicing it [:]
Upvotes: 0
Views: 58
Reputation: 7361
This is also related to mutable and immutable types. You are dealing with lists of lists, which are lists of mutables. So the inner lists are passed by reference, even if you use [:]
which makes a shallow copy: a copy of the container, but holding references to the inner object if they are mutables.
That's why, when you change the inner lists, you are changing the same inner lists each time. They are all references to the same lists.
Have a look at the copy docs to more details about shallow copies and deep copies. This will also give you a solution: use a deep copy.
In each function, replace:
l = list(m)
with:
l = copy.deepcopy(m)
Upvotes: 1