Transpose Matrix from python

Asked by At

I really don't understand the logic here.......

def transpose(A):
    output = [['']*len(A)] * len(A[0])
    for j in range(len(A[0])):
        for i in range(len(A)):
            output[j][i] = A[i][j]
    return output

Input: [[1,2,3],[4,5,6],[7,8,9]]

Expected Output: [[1,4,7],[2,5,8],[3,6,9]]

My Output: [[3,6,9], [3,6,9], [3,6,9]]

I know I can use zip to solve this problem easily, but I just want to know why this code will return duplicated lists.

New update, I have added some print to understand the process

def transpose(A):
    output = [['']*len(A)] * len(A[0])
    for j in range(len(A[0])):
        for i in range(len(A)):
            output[j][i] = A[i][j]
            print(j)
            print(i)
            print(output)
    return output

And the outputs are:

0
0
[[1, '', ''], [1, '', ''], [1, '', '']]
0
1
[[1, 4, ''], [1, 4, ''], [1, 4, '']]
0
2
[[1, 4, 7], [1, 4, 7], [1, 4, 7]]
1
0
[[2, 4, 7], [2, 4, 7], [2, 4, 7]]
1
1
[[2, 5, 7], [2, 5, 7], [2, 5, 7]]
1
2
[[2, 5, 8], [2, 5, 8], [2, 5, 8]]
2
0
[[3, 5, 8], [3, 5, 8], [3, 5, 8]]
2
1
[[3, 6, 8], [3, 6, 8], [3, 6, 8]]
2
2
[[3, 6, 9], [3, 6, 9], [3, 6, 9]]
[[3, 6, 9], [3, 6, 9], [3, 6, 9]]

So, for example, the very first step of the loop. j = 0 and i = 0. However, output[0][0],output[1][0],and output[2][0] are all changed by the loop. Why is that??????

I am so confused right now. I have written the same code in Java and it runs properly.

public class TransposeMatrix {
    public static int[][] transpose(int[][] A) {
        int[][] result = new int[A[0].length][A.length];
        for (int j = 0; j < A[0].length; j++) {
            for (int i = 0; i < A.length; i++) result[j][i] = A[i][j];
        }
        return result;
    }
}

The link of this problem is: https://leetcode.com/problems/transpose-matrix/

1 Answers

1
Community On

When you multiply lists in python like that, you don't actually create new lists but several references to the same list. Thus, when you change the value in one list, you also change it in the other lists. That's why your output is [[3,6,9], [3,6,9], [3,6,9]]; it's simply the last of the three lists (i.e. from the last value of the for loop).

Instead, you can do this:

def transpose(A):
    output = [['']* (len(A)) for y in range(len(A[0]))]
    # or: output = [['' for x in range(len(A))] for y in range(len(A[0]))]
    for j in range(len(A[0])):
        for i in range(len(A)):
            output[j][i] = A[i][j]
    return output

transpose([[1,2,3],[4,5,6],[7,8,9]])

which returns [[1,4,7],[2,5,8],[3,6,9]].

Hope this helps!