3

I am trying to change an element in a Python list. Following the tutorial on https://www.programiz.com/python-programming/matrix, I came up with the code below.

 matrix = [[0]*6]*3
 print(matrix)
 matrix[0][0] = 2
 print(matrix)

Upon running the code, I received the following output:

[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
[[2, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0]]

Notice the last line of output, how the first element of every sub-list is set to 2. How do I make it so that only the first element of the first list is changed.

Cong Ma
  • 10,692
  • 3
  • 31
  • 47

2 Answers2

3

This is a classic python gotcha to do with the fact that all python objects are references. In your case this means that matrix[0] is matrix[1] is matrix[2] since is is True if two objects are the same thing in memory.

Do this instead

matrix = [[0]*6 for _ in range(3)]

Now matrix[0] is matrix[1] is matrix[2] returns False.

Alternatively, use numpy which was made for manipulating numerical arrays without these issues.

FHTMitchell
  • 11,793
  • 2
  • 35
  • 47
0

This is because each row in your matrix isn't an individual array, but a reference to the same array.

The following will print out the memory location for each row:

for row in matrix:
    print(id(row))

Notice that they are all the same. This is because lists in python are passed by-reference, not copying each individual value.

What you are essentially doing in part two of your code is:

row = [0] * 6
matrix = [row, row, row]

You might be better off with something like this:

matrix = [[0 for _ in range(6)] for _ in range(3)]
matrix[0][0] = 2
[[2, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]

Which creates a new array full of 0 for each row you are creating in the matrix.

SCB
  • 5,821
  • 1
  • 34
  • 43