0

I'm trying to change the value of a certain element in a 2D array. the 2D array is a num1 by num2 matrix with every element as 0. I'm trying to change the Rth row Cth column of the matrix to 1

matrix = []
def make_matrix(num1, num2):
    row = []
    for i in range(num1):
        row.append(0)
    for i in range(num2):
        matrix.append(row)

def change_to_one(R, C):
    matrix[R-1][C-1] = 1

make_matrix(3, 2)
change_to_one(2, 1)
print(matrix)

it prints [[1, 0, 0], [1, 0, 0]] instead of [[0, 0, 0], [1, 0, 0]]

F Blanchet
  • 1,430
  • 3
  • 21
  • 32

2 Answers2

1

There are two problems in your code:

  • You are using a reference to the original list when you do matrix.append(row[:]). This can be circumvented by just copying the elements of the list as row[:] instead of using row. Otherwise, whatever changes you do to the first row, will also be reflected in all the other rows.
  • You forgot to return after modifying the matrix. This is not a major problem in your case as the scope of your matrix is global.

matrix = []

def make_matrix(num1, num2):
    row = []
    for i in range(num1):
        row.append(0)
    for i in range(num2):
        matrix.append(row[:]) # <--- Use row[:] instead of row

def change_to_one(R, C):
    matrix[R-1][C-1] = 1
    return matrix # <---- return from here 

make_matrix(3, 2)
matrix = change_to_one(2, 1) # <---- save the returned result in a variable 
print(matrix)

# [[0, 0, 0], [1, 0, 0]]
Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • `matrix` in the function is used as a "global" variable. It seems to work even without the `return`, correct? – Dino May 27 '19 at 00:43
  • 1
    @Dino: You are right. Here it will work without return too, which is in general, not a good practice. I will add your point to my answer though – Sheldore May 27 '19 at 00:45
1

This has to do with pointers. You first define row=[] When you do this matrix.append(row) num2 times, you are appending the address of row, hence if you change row anytime, it will be broadcasted subsequently.

In other words, changing data in row will change data everywhere you appended row to which in your case is all rows of 2D matrix.

Try this code:

def make_matrix(num1, num2):
    for i in range(num2):
      row = []
      for i in range(num1):
          row.append(0)
      matrix.append(row)

Here we create a new row everytime and then append it to our matrix, this way changes in any row will not be broadcasted.

hsnsd
  • 1,728
  • 12
  • 30