0

I'm working on this website called codefights.com, and the task given in one of the coding challenges is described in this image.

I'm trying to take add 1 to a specific position in a 2d array.

I use the following line to do so: newMatrix[i+1][j] += 1 but when I do that it, for some reason adds 1 to every array inside the array at that same position, not just at the one position I specified (Example below)

I would call the function with this array:

minesweeper([[true,false,false], [false,true,false], [false,false,false]])

def minesweeper(matrix):
    rowlen = len(matrix[0])
    columnLen = len(matrix)

    newMatrix = [[0]*(rowlen+2)] * (columnLen+2) #grid of zeros with padding
    truePosArray = []
    y = 0
    for x in matrix: #calculate the positions of the true instance(s)
        try:
            truePosArray.append([y+1, x.index(True)+1])
        except ValueError:
            pass
        y += 1
    if truePosArray == []:
        return [[0]*(rowlen)] * (columnLen)

    for y in truePosArray: #run once for every true instance
        i = y[0]
        j = y[1]
        newMatrix[i+1][j] += 1
        print(newMatrix)

When I print the first result of newMatrix during the last, the output is: [[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]

Note: there are a padding of zeros around the array.

Why do you guys think this is happening, when I try to perform a similar action like this:

newMatrix = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

i = 0
j = 1

newMatrix[i][j] += 1
print(newMatrix)

The output is [[0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

Can anyone help me understand why this is happening? It has been confusing me for such a long time.

Thanks for your help!

1 Answers1

0

Right now you have a common misconception about references. When you create an array such as here:

newMatrix = [[0]*(rowlen+2)] * (columnLen+2)

You get a neat 2D array. However, there aren't actually separate copies of [[0]*(rowlen+2)], each spot in that 2D array actually points to the same array. Therefore, when you change one element in one of those arrays, that same element is changed for all of the arrays. To make actual copies of the array, switch your code to use a list comprehension:

newMatrix = [[[0]*(rowlen+2)]  for i in range(columnLen+2)]
Primusa
  • 13,136
  • 3
  • 33
  • 53