161

I am trying to create a matrix transpose function for python but I can't seem to make it work. Say I have

theArray = [['a','b','c'],['d','e','f'],['g','h','i']]

and I want my function to come up with

newArray = [['a','d','g'],['b','e','h'],['c', 'f', 'i']]

So in other words, if I were to print this 2D array as columns and rows I would like the rows to turn into columns and columns into rows.

I made this so far but it doesn't work

def matrixTranspose(anArray):
    transposed = [None]*len(anArray[0])
    for t in range(len(anArray)):
        for tt in range(len(anArray[t])):
            transposed[t] = [None]*len(anArray)
            transposed[t][tt] = anArray[tt][t]
    print transposed
jfs
  • 399,953
  • 195
  • 994
  • 1,670
Julio Diaz
  • 9,067
  • 19
  • 55
  • 70

19 Answers19

346

Python 2:

>>> theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> zip(*theArray)
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]

Python 3:

>>> [*zip(*theArray)]
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 16
    if you're going to iterate through the results, `izip` from `itertools` can save memory for large arrays. – Antony Hatchkins Mar 28 '13 at 08:38
  • 1
    How would you have it return a list for the sub lists? Like `[['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]` instead of `[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]`? – acollection_ Feb 28 '16 at 03:15
  • 20
    @acollection_: `map(list, zip(*theArray))`. – jfs Feb 28 '16 at 12:45
  • Why the asterisk? – FreelanceConsultant Oct 20 '16 at 16:38
  • @user3728501 [What does asterisk * mean in Python?](http://stackoverflow.com/q/400739/4279) – jfs Oct 20 '16 at 17:14
  • @J.F.Sebastian I read that but unfortunately I didn't understand any of it – FreelanceConsultant Oct 20 '16 at 17:23
  • @user3728501 have you just read the question, its duplicate and their more than a dozen answers in 8 minutes? Or have you seen them before? [The argument unpacking is discussed even in the official Python tutorial](https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists). If it is still unclear; pick an answer that you understand the most and ask a separate question about the unclear parts. – jfs Oct 20 '16 at 18:01
  • 1
    @AntonyHatchkins This is not needed with Python 3.0 and above. There, `zip` already returns an iterator: https://docs.python.org/3.0/whatsnew/3.0.html#views-and-iterators-instead-of-lists – xuiqzy May 09 '20 at 13:06
  • 1
    @xuiqzy It's not that I'm not aware of it, but that's true. – Antony Hatchkins May 09 '20 at 17:30
68
>>> theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> [list(i) for i in zip(*theArray)]
[['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']]

the list generator creates a new 2d array with list items instead of tuples.

sqwerl
  • 778
  • 6
  • 4
  • This is the way to go if you want to assign the result to a variable (as opposed to, e.g., iterating over it directly) — assuming you want lists instead of tuples, as mentioned. – ASL Oct 17 '16 at 19:34
  • Another option (as implied by the comments in the accepted answer) would be: `list(map(list, zip(*theArray)))` – ASL Oct 18 '16 at 12:42
42

If your rows are not equal you can also use map:

>>> uneven = [['a','b','c'],['d','e'],['g','h','i']]
>>> map(None,*uneven)
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', None, 'i')]

Edit: In Python 3 the functionality of map changed, itertools.zip_longest can be used instead:
Source: What’s New In Python 3.0

>>> import itertools
>>> uneven = [['a','b','c'],['d','e'],['g','h','i']]
>>> list(itertools.zip_longest(*uneven))
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', None, 'i')]
bigjim
  • 938
  • 1
  • 9
  • 18
20

Much easier with numpy:

>>> arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> arr
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> arr.T
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])
>>> theArray = np.array([['a','b','c'],['d','e','f'],['g','h','i']])
>>> theArray 
array([['a', 'b', 'c'],
       ['d', 'e', 'f'],
       ['g', 'h', 'i']], 
      dtype='|S1')
>>> theArray.T
array([['a', 'd', 'g'],
       ['b', 'e', 'h'],
       ['c', 'f', 'i']], 
      dtype='|S1')
Irshad Bhat
  • 8,479
  • 1
  • 26
  • 36
9

The problem with your original code was that you initialized transpose[t] at every element, rather than just once per row:

def matrixTranspose(anArray):
    transposed = [None]*len(anArray[0])
    for t in range(len(anArray)):
        transposed[t] = [None]*len(anArray)
        for tt in range(len(anArray[t])):
            transposed[t][tt] = anArray[tt][t]
    print transposed

This works, though there are more Pythonic ways to accomplish the same things, including @J.F.'s zip application.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 1
    Note that this implementation doesn't work with matrices that have different numbers of columns and rows – Vector Nov 10 '19 at 03:18
5

The "best" answer has already been submitted, but I thought I would add that you can use nested list comprehensions, as seen in the Python Tutorial.

Here is how you could get a transposed array:

def matrixTranspose( matrix ):
    if not matrix: return []
    return [ [ row[ i ] for row in matrix ] for i in range( len( matrix[ 0 ] ) ) ]
leetNightshade
  • 2,673
  • 2
  • 36
  • 47
5

To complete J.F. Sebastian's answer, if you have a list of lists with different lengths, check out this great post from ActiveState. In short:

The built-in function zip does a similar job, but truncates the result to the length of the shortest list, so some elements from the original data may be lost afterwards.

To handle list of lists with different lengths, use:

def transposed(lists):
   if not lists: return []
   return map(lambda *row: list(row), *lists)

def transposed2(lists, defval=0):
   if not lists: return []
   return map(lambda *row: [elem or defval for elem in row], *lists)
Franck Dernoncourt
  • 77,520
  • 72
  • 342
  • 501
2

This one will preserve rectangular shape, so that subsequent transposes will get the right result:

import itertools
def transpose(list_of_lists):
  return list(itertools.izip_longest(*list_of_lists,fillvalue=' '))
Vanuan
  • 31,770
  • 10
  • 98
  • 102
2

you can try this with list comprehension like the following

matrix = [['a','b','c'],['d','e','f'],['g','h','i']] n = len(matrix) transpose = [[row[i] for row in matrix] for i in range(n)] print (transpose)

sharif_42
  • 511
  • 4
  • 11
1

If you want to transpose a matrix like A = np.array([[1,2],[3,4]]), then you can simply use A.T, but for a vector like a = [1,2], a.T does not return a transpose! and you need to use a.reshape(-1, 1), as below

import numpy as np
a = np.array([1,2])
print('a.T not transposing Python!\n','a = ',a,'\n','a.T = ', a.T)
print('Transpose of vector a is: \n',a.reshape(-1, 1))

A = np.array([[1,2],[3,4]])
print('Transpose of matrix A is: \n',A.T)
Hassan Bahaloo
  • 171
  • 1
  • 2
1

You may do it simply using python comprehension.

arr = [
    ['a', 'b', 'c'], 
    ['d', 'e', 'f'], 
    ['g', 'h', 'i']
]
transpose = [[arr[y][x] for y in range(len(arr))] for x in range(len(arr[0]))]
pylover
  • 7,670
  • 8
  • 51
  • 73
  • Although this may be a correct answer. Two lines of code isn't very useful without an explanation of what and how it solves the original question. Please provide details to your answer. – RyanNerd Sep 27 '19 at 22:29
  • 1
    when posting a new answer to an old question, expectations are high. Please don't post an inferior solution to the ones already posted – Jean-François Fabre Sep 28 '19 at 09:05
-1
def matrixTranspose(anArray):
  transposed = [None]*len(anArray[0])

  for i in range(len(transposed)):
    transposed[i] = [None]*len(transposed)

  for t in range(len(anArray)):
    for tt in range(len(anArray[t])):            
        transposed[t][tt] = anArray[tt][t]
  return transposed

theArray = [['a','b','c'],['d','e','f'],['g','h','i']]

print matrixTranspose(theArray)
Olli
  • 1,231
  • 15
  • 31
Asterisk
  • 3,534
  • 2
  • 34
  • 53
-1
import  numpy as np #Import Numpy 

m=int(input("Enter row")) #Input Number of row

n=int(input("Enter column")) #Input number of column

a=[] #Blank Matrix

for i in range(m): #Row Input

    b=[] #Blank List

    for j in range(n):#column Input

        j=int(input("Enter Number in Pocket ["+str(i)+"]["+str(j)+"]")) #sow Row Column Number 

        b.append(j) #addVlaue to list

    a.append(b)#Add List To Matrix

a=np.array(a)#convert 1matrix as Numpy

b=a.transpose()#transpose Using Numpy

print(a) #Print Matrix 

print(b)#print Transpose Matrix
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sanjay Rai
  • 27
  • 3
-2
#generate matrix
matrix=[]
m=input('enter number of rows, m = ')
n=input('enter number of columns, n = ')
for i in range(m):
    matrix.append([])
    for j in range(n):
        elem=input('enter element: ')
        matrix[i].append(elem)

#print matrix
for i in range(m):
    for j in range(n):
        print matrix[i][j],
    print '\n'

#generate transpose
transpose=[]
for j in range(n):
    transpose.append([])
    for i in range (m):
        ent=matrix[i][j]
        transpose[j].append(ent)

#print transpose
for i in range (n):
    for j in range (m):
        print transpose[i][j],
    print '\n'
-3
a=[]
def showmatrix (a,m,n):
    for i in range (m):
        for j in range (n):
            k=int(input("enter the number")
            a.append(k)      
print (a[i][j]),

print('\t')


def showtranspose(a,m,n):
    for j in range(n):
        for i in range(m):
            print(a[i][j]),
        print('\t')

a=((89,45,50),(130,120,40),(69,79,57),(78,4,8))
print("given matrix of order 4x3 is :")
showmatrix(a,4,3)


print("Transpose matrix is:")
showtranspose(a,4,3)
Sir l33tname
  • 4,026
  • 6
  • 38
  • 49
-3
def transpose(matrix):
   x=0
   trans=[]
   b=len(matrix[0])
   while b!=0:
       trans.append([])
       b-=1
   for list in matrix:
       for element in list:
          trans[x].append(element)
          x+=1
       x=0
   return trans
-3
def transpose(matrix):
    listOfLists = []
    for row in range(len(matrix[0])):
        colList = []
        for col in range(len(matrix)):
            colList.append(matrix[col][row])
    listOfLists.append(colList)

    return listOfLists
  • Its a simple implementation for a transpose, though there are libraries like mentioned in other answers are also available. – Ravneet Singh Aug 14 '17 at 22:00
-3

`

def transpose(m):
    return(list(map(list,list(zip(*m)))))

`This function will return the transpose

-3

Python Program to transpose matrix:

row,col = map(int,input().split())
matrix = list()

for i in range(row):
    r = list(map(int,input().split()))
    matrix.append(r)

trans = [[0 for y in range(row)]for x in range(col)]

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

for i in range(len(trans)):
    for j in range(len(trans[0])):
        print(trans[i][j],end=' ')
    print(' ')
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
Manish Rana
  • 315
  • 2
  • 5