0

I've written the following code below but the output of it is not as I expected. Does anyone know why it is behaving like this?

N.B.: I know the code doesn't transpose the list correctly - I stumbled across this strange behavior whilst writing the function.

matrix = [
     [1, 2, 3, 4],
     [5, 6, 7, 8],
     [9, 10, 11, 12],
 ]

transposed = []
for i in range(4):
    print("i", i)
    t_list = []
    for row in matrix:
        print("row", row)
        t_list.append(row[i])
        print("t_list**********", t_list)
        transposed.append(t_list)

        print("transposed//////////////", transposed)

The output I would expect from this function at the end of the first row is:

[[1], [1, 5], [1, 5, 9]]

Instead, it seems to output:

[[1, 5, 9], [1, 5, 9], [1, 5, 9]]

Does anyone know why?

Thanks!

Barmar
  • 741,623
  • 53
  • 500
  • 612
Valencia
  • 15
  • 3
  • You may find this article helpful: [Facts and myths about Python names and values](http://nedbatchelder.com/text/names.html), which was written by SO veteran Ned Batchelder. – PM 2Ring Apr 29 '17 at 09:31
  • BTW, the quick way to transpose a 2D list in pure Python is `list(zip(*matrix))`. That makes a list of tuples, if you need a list of lists, use `[list(u) for u in zip(*matrix)]`. – PM 2Ring Apr 29 '17 at 09:35
  • On a related note, see http://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly – PM 2Ring Apr 29 '17 at 10:01

3 Answers3

0

It seems like an indentation issue in the line transposed.append(t_list):

transposed = []
for i in range(4):
    t_list = []
    for row in matrix:
        t_list.append(row[i])

    transposed.append(t_list)

This code prints:

[[1, 5, 9],
 [2, 6, 10],
 [3, 7, 11],
 [4, 8, 12]]

Transpose has been implemented in numpy and it works with python arrays:

import numpy as np
np.transpose(matrix)
Elisha
  • 23,310
  • 6
  • 60
  • 75
0

The problem is here:

t_list = []
for row in matrix:
    t_list.append(row[i])
    transposed.append(t_list)

Inside the loop the contents of the list object t_list changes, but the list object itself remains the same. Thus, transposed gets the same object for each row.

This is fixed by appending a copy of the current list instead of the original list object.

transposed.append(list(t_list))
Heiko Oberdiek
  • 1,598
  • 10
  • 12
0

Key point is to make a copy of inner list and then append in the outer list.

copy = t_list[::]

It is because list is an object and it is a refresnce. so when you append another item in a list, it will be updated over all places where that objects exists. In your case, you are appending list into a list and then updating the inner list which causes the previous list items to update as well. You need to append a copy of a list in transposed list. Here is a solution.

transposed = []
for i in range(4):
print("i", i)
t_list = []
for row in matrix:
    print("row", row)
    t_list.append(row[i])
    print("t_list**********", t_list)
    transposed.append(t_list[::])

    print("transposed//////////////", transposed)
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60