Search code examples
python-3.xmatrixpylintenumerate

What is the pythonic solution to enumerate and update items from a matrix?


I did a for loop using enumerate from values in a matrix and tried assigning a value to the items that are different than 0 while appending to a list elements that are equal to 0. The fact is that original matrix don't get updated.

Sample code:

matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
current = []
for x, i in enumerate(matrix):
    for y, j in enumerate(i):
        if j == 0:
            current.append((x, y))
        else:
            #matrix[x][y] = -1 # This works
            j = -1 # This doesn't

Since this doesn't work, there is no utility in using enumerate for that case. So I changed the code to:

matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
current = []
for x in range(len(matrix)):
    for y in range(len(matrix[0])):
        if matrix[x][y] == 0:
            current.append((x, y))
        else:
            matrix[x][y] = -1

The code above IMO is much less readble and also pylint suggests against using that with:

C0200: Consider using enumerate instead of iterating with range and len (consider-using-enumerate)


Solution

  • You can't just update 2d array in-place through assigning to local variable j = -1 (which is reinitialized on each loop iteration for y, j in enumerate(i)).

    In your simple case you can update your matrix with the following simple traversal:

    matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
    for i, row in enumerate(matrix):
        for j, val in enumerate(row):
            if val != 0: matrix[i][j] = -1
    
    print(matrix)    # [[0, 0, 0], [0, -1, 0], [-1, -1, -1]]
    

    Though Numpy provides a more powerful way for updating matrices:

    import numpy as np
    
    matrix = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 1]])
    matrix = np.where(matrix == 0, matrix, -1)
    
    print(matrix)