2

I wrote a transpose matrix function however, when I try to run it the values inside the output becomes the same in the end. Attached there is a picture of the output. My code is also commented.

def transpose(any_matrix):
    _row = len(any_matrix)
    _col = len(any_matrix[0])
    temp_matrix = []
    #multiplies [0] by the number of rows (old) to create new row
    temp_row = [0]*_row
    #creates matrix with number of columns as rows  
    for x in range(_col):
        temp_matrix += [temp_row]
    for r in range(len(any_matrix)):
        for c in range(len(any_matrix[0])):
            value = any_matrix[r][c]
            temp_matrix[c][r] = value
return temp_matrix

a = [[4, 5, 6], [7,8,9]]
print(transpose(a))

    #input [[4,5,6]
    #       [7,8,9]]

    #correct answer [   [4,7],
    #                   [5,8],
    #                   [6,9]   ]

I prefer not to use other libraries such as numpy etc. output

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I'm not getting the same output: `[[6, 9], [6, 9], [6, 9]]` still looking for an answer though – David Culbreth Sep 27 '18 at 20:14
  • 1
    See https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly . The rows of your `temp_matrix` are all the same `temp_row` list. – Thierry Lathuille Sep 27 '18 at 20:17
  • The idiomatic way to transpose a rectangular list of lists, e.g., `a = [list(range(n,n*6,n)) for n in range(1,12)]` is `a_transpose = [list(col) for col in zip(*a)]` – gboffi Sep 27 '18 at 21:32

1 Answers1

3

This behavior is more fully explained here, so I recommend you take a look.

when you use the line temp_matrix += [temp_row], you are adding the list object temp_row to the array (three times in this case.)

When you say

temp_matrix[c][r] = value

the value is overwritten in the temp_row object, because temp_matrix[c] is the same object as temp_row, so when you go to print out the whole temp_matrix, it prints out what it is: 3 references to the same matrix.

Using the list.copy() method should get around this undesired effective pointer-passing by adding a new list object (that is a copy of the temp_row) to temp_matrix. Here's some working code:

def transpose(any_matrix):
    _row = len(any_matrix)
    _col = len(any_matrix[0])
    temp_matrix = []
    #multiplies [0] by the number of rows (old) to create new row
    temp_row = [0]*_row
    #creates matrix with number of columns as rows  
    for x in range(_col):
        temp_matrix += [temp_row.copy()]
    for r in range(len(any_matrix)):
        for c in range(len(any_matrix[0])):
            value = any_matrix[r][c]
            temp_matrix[c][r] = value
    return temp_matrix

a = [[4, 5, 6], [7,8,9]]
print(transpose(a))

    #input [[4,5,6]
    #       [7,8,9]]

    #correct answer [   [4,7],
    #                   [5,8],
    #                   [6,9]   ]
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
David Culbreth
  • 2,610
  • 16
  • 26