2

I've been scanning the forums and haven't found an answer yet that I can apply to my situation. I need to be able to take an n by n array and transpose it in Python-3. The example given is that I have this list input into the function:

[[4, 2, 1], ["a", "a", "a"], [-1, -2, -3]] and it needs to be transposed to read:

[[4, 'a', -1], [2, 'a', -2], [1, 'a', -3]] So basically reading vertically instead of horizontally.

I CANNOT use things like zip or numpy, I have to make my own function.

Been rattling my brain at this for two nights and it's a huge headache. If anyone could help and then provide an explanation so I can learn it, I'd be grateful.

Edit:

I should add for reference sake that the argument variable is M. The function we're supposed to write is trans(M):

UncleChaos
  • 29
  • 1
  • 3
  • Hint: Wikipedia says, "the `i`th row, `j`th column element of A_transposed is the `j`th row, `i`th column element of A." – Kevin Apr 30 '14 at 16:33
  • use the numpy lib. something like this **np.array([5,4])[np.newaxis]** and print the result **print a.T** – Zuko Apr 30 '14 at 16:35
  • Does this answer your question? [Transpose list of lists](https://stackoverflow.com/questions/6473679/transpose-list-of-lists) – ClimateUnboxed Nov 16 '22 at 12:46

5 Answers5

3

A one-liner:

def trans(M):
    return [[M[j][i] for j in range(len(M))] for i in range(len(M[0]))]

result:

>>> M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> trans(M)
[[1, 4, 7], [2, 5, 8], [3, 6, 9]
# or for a non-square matrix:
>>> N = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
>>> trans(N)
[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

Additional Note: If you look up the tutorial on list comprehension, one of the examples is in fact transposition of a matrix array.

mata
  • 67,110
  • 10
  • 163
  • 162
  • Thank you to both you and @Morten Zilmer. I'm not quite sure I understand why it works though. How does the "for i in range(len(M[0]))] part work? – UncleChaos Apr 30 '14 at 17:26
  • The assumption is that all rows (inner lists) have same length, which is the number of columns given by `len(M[0])`. The `range(len(M[0]))` iterates over the columns, and creates rows in the transposed matrix based on all row elements in each column of M. – Morten Zilmer Apr 30 '14 at 17:54
  • @UncleChaos - it's called list comprehension ([explained here](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) - the explanation and examples in the tutorial should make it clear how it works) – mata Apr 30 '14 at 17:59
1

A variant that should work for matrices with irregular row lengths:

m=[[3, 2, 1],
   [0, 1],
   [2, 1, 0]]

m_T = [ [row[c] for row in m if c < len(row)] for c in range(0, max([len(row) for row in m])) ]
Scott Guthart
  • 407
  • 5
  • 8
0

Here is an in place solution that works for square matrices:

def trans(M):
  n = len(M)
  for i in range(n - 1):
    for j in range(i + 1, n):
      M[i][j], M[j][i] = M[j][i], M[i][j]

Example Usage:

def print_matrix(M):
  for row in M:
    for ele in row:
      print(ele, end='\t')
    print()
  
M = [[4, 2, 1], ["a", "a", "a"], [-1, -2, -3]]
print('Original Matrix:')
print_matrix(M)
trans(M)
print('Transposed Matrix:')
print_matrix(M)

Output:

Original Matrix:
4   2   1
a   a   a
-1  -2  -3
Transposed Matrix:
4   a   -1
2   a   -2
1   a   -3
Sash Sinha
  • 18,743
  • 3
  • 23
  • 40
0
y=([1,2], [3,4], [5,6])

transpose=[[row[i] for row in y] for i in range(len(y[0]))]

the output is

[[1, 3, 5], [2, 4, 6]]
ClimateUnboxed
  • 7,106
  • 3
  • 41
  • 86
0

You can also use the function in numpy to transpose - if you need the answer as a list it is straightforward to convert back using tolist:

from numpy import transpose 
M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

transpose(M).tolist()

the output is

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

Haven't timed it (no time!) but I strongly suspect this will be a lot faster than iterators for large arrays, especially if you don't need to convert back to a list.

ClimateUnboxed
  • 7,106
  • 3
  • 41
  • 86