0

NxN Matrix transposing gives wrong answers upon making "result" matrix = input matrix

Novice programmer here. I am trying to transpose a NxN matrix. Putting the code here to make the problem clear:

def flippingMatrix(matrix):
    result=[[0 for i in range(len(matrix))] for j in range(len(matrix))]
    for i in result:
        print(i)
    
    for i in range(len(matrix)):
        for j in range(len(matrix)):
            result[j][i]=matrix[i][j]
    
    for i in result:
        print(i)
            

# //Main Program//
n = int(input().strip())

matrix = []

for i in range(n):
    matrix.append(list(map(int, input().rstrip().split())))

result = flippingMatrix(matrix)

Now, if we run this program, we input 'N' which is no. of rows and columns. And in the next line, elements into the matrix. This is the input that I gave:

2

1 2

3 4

The output:

[0, 0]     //This is the result matrix that I made//
[0, 0]
[1, 3]     //The final result matrix//
[2, 4]

Coming to the problem: If, I assign the

"result=matrix" 

instead of

result=[[0 for i in range(len(matrix))] for j in range(len(matrix))]

I get the wrong answer. I am assuming that we need a result matrix as only a layout of NxN matrix. Then why does making the result same as input gives wrong answer? It is anyways going to be overwritten.

With the same input as earlier, I get the following output:

[1, 2]     //Initial result matrix which is the copied input matrix//
[3, 4]
[1, 2]     //The final result matrix//
[2, 4]

I apologize if the problem is a bit unclear, I tried my best. If anyone needs further explanation, comment on this post and I will try to explain my problem

EDIT: The new code that I am using after I was suggested an edit. The new code is as follows and I am facing the same problem

def flippingMatrix(matrix):
result=matrix
for i in result:
    print(i)

for i in range(len(matrix)):
    for j in range(len(matrix)):
        result[j][i]=matrix[i][j]

return result
        

# //Main Program//
n = int(input().strip())

matrix = []

for i in range(n):
    matrix.append(list(map(int, input().rstrip().split())))

result = flippingMatrix(matrix)
print(result)

Now the problem here might be because of the assignment statement result = matrix. But I don't think result matrix should be zero in order to be rewritten.

  • `result = matrix` doesn't make a copy: it results in `result` and `matrix` being the same thing. That's a problem, because think about the case where `i=1, j=0`. Then you're doing `result[0][1] = matrix[1][0]`. But what's the value of `matrix[1][0]` at that point? It's not the original value, it's the value you assigned to `result[1][0]` on an earlier iteration of the loop. – slothrop May 22 '23 at 13:12
  • @slothrop Thankyou for the insight. So you are telling me that when I write 'result = matrix', the matrix and result are entangled? If I change one of the matrix, the other will change too? – Flying_Zues May 23 '23 at 10:11
  • Correct, writing `result = matrix` simply means that `result` and `matrix` are aliases for the same object. See: https://nedbatchelder.com/text/names.html – slothrop May 23 '23 at 14:33
  • Hi @slothrop. I am still unclear. How can they be entangled? If I change the result, how will the matrix change as well? I am confused regarding this. I hope you can help!! – Flying_Zues May 25 '23 at 11:29
  • It's not that `result` and `matrix` are two objects which are entangled. It's that `result` and `matrix` are different names referring to the **same object**. For example, try `print(id(result), id(matrix))` and you'll see that the two IDs are the same. – slothrop May 25 '23 at 11:46
  • If you want `result` to be a new object with identical data to `matrix`, then what you can do is `import copy` followed by `result = copy.deepcopy(matrix)`. – slothrop May 25 '23 at 11:49
  • See for example: https://stackoverflow.com/questions/2541865/copying-nested-lists-in-python – slothrop May 25 '23 at 12:06
  • Thank you @slothrop for this explanation and for linking the post. The post was explained well. I think the reason for result=matrix not working is that it is a list inside a list. I read the whole post and now I understand it better. Thanks again. I don't know how to mark your comment as answer but yours surely is! – Flying_Zues May 26 '23 at 10:30
  • Cool! I think the answers on the linked question already cover it pretty well. By the way, if you want a concise way of transposing a 2D array, you can do `result = list(zip(*matrix))`. But it's useful to go through the process you have, because you learn more about the structures involved. – slothrop May 26 '23 at 10:40
  • Thank you for this insight again! Sure I am learning a lot of new things by uploading one question here. Thanks again! – Flying_Zues May 27 '23 at 11:19

2 Answers2

0

Your function should have a return, if you assign matrix=result inside its scope, this won't propagate outside of the function, it's only a reference/pointer assignment. The values of each matrix is not copied.

Try:

def flippingMatrix(matrix):
    result=[[0 for i in range(len(matrix))] for j in range(len(matrix))]
    for i in range(len(matrix)):
        for j in range(len(matrix)):
            result[j][i]=matrix[i][j]
    return result
            

# //Main Program//
n = int(input().strip())

matrix = []

for i in range(n):
    matrix.append(list(map(int, input().rstrip().split())))

print(matrix)
result = flippingMatrix(matrix)
print( result)

Tested here for n = 3:

def flippingMatrix(matrix):
    result=[[0 for i in range(len(matrix))] for j in range(len(matrix))]
    for i in range(len(matrix)):
        for j in range(len(matrix)):
            result[j][i] = matrix[i][j]
    return result
            

# //Main Program//
n = 3
matrix = [[i+j*n for i in range(n)] for j in range(3)]
print( matrix) # returns [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

matrix = flippingMatrix(matrix)
print( matrix) # returns [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
Learning is a mess
  • 7,479
  • 7
  • 35
  • 71
  • Hello, Thank you for this correction. I will apply this in my next program. The problem however still persists and returning the variable doesn't solve that issue – Flying_Zues May 23 '23 at 10:12
  • 1
    Please share your code, I have just tested again my code for matrices of linear size = 2 and 3 and it seems to work, see my edit – Learning is a mess May 23 '23 at 10:18
  • Hello. sorry for the late reply and Thank you for using code on your own as well. I have edited my post with the updated code but it seems I am facing the same issue. I hope you can help. Thanks again`` – Flying_Zues May 25 '23 at 11:27
0

So I learned by talking in comments with @slothrop, Python doesn't take copying of lists inside of lists lightly. In order to make a copy, I have to use different commands like so that it actually makes an independent 2D array:

b = copy.deepcopy(a)
b = [item[:] for item in a]
b = [item.copy() for item in a]
b = [list(item) for item in a]
b = [copy.copy(item) for item in a]
b = []; b.extens[a]

The link to such other question is here.

  • It looks like `b = []; b.extend[a]` is a mistake in the answer to the other question. That's the same as doing `b = [item for item in a]` instead of `b = [item[:] for item in a]`. All of the other things you suggest would work fine for a 2D array. – slothrop May 26 '23 at 10:43