1

I have an assignment to do, which is:

Write a function transpose which takes in a matrix and transposes it. Basically, this converts a m x n matrix into a n x m matrix.

I wrote a code which seems sensible, but it doesnt get me the result I want. Can anyone point out what is wrong with my code?

def transpose(matrix):
    new_matrix=[[]]*len(matrix[0])
    for row in matrix:
        i=0
        for j in row:
            new_matrix[i]+=[j]
            i+=1
    return new_matrix

Test case:

print(transpose([[ 1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]))
5
  • 1
    Duplicate the original matrix, loop over i,j and keep doing new[j][i] = original[i][j] Commented Mar 5, 2018 at 12:23
  • [list(i) for i in zip(*a)] try this. this will transpose your matrix. Commented Mar 5, 2018 at 12:31
  • Found a dupe : stackoverflow.com/questions/1807026/… Commented Mar 5, 2018 at 12:39
  • Possible duplicate of Initialize a list of objects in Python Commented Mar 5, 2018 at 12:39
  • Is there other methods other than zip, dont think its expected of me to use zip? @UbdusSamad How would u predetermine the dimensions of the new matrix? I tried it with 2 ranges and it gives me Index Error: index out of range Commented Mar 5, 2018 at 12:56

2 Answers 2

1

If you use the * to multiply some values in a list-initialisation, be careful. You might end up with references that point multiple times to the same value:

l = [ [] ]*3
print(l)

l[1].append(34)  # change only "the first" list by appending smth
print(l)

Output:

[[], [], []]
[[34], [34], [34]]  # they are all "the same data" reference

There is an built-in zip() that does exactly your transposing:

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


l_t = [ list(x) for x in zip(*l)]  # one-line solutions for transposing ;)

print(l)
print(l_t) # transposed

Zip has the limitation that it only works to the length of the smallest sublists - yours are all equal so all is fine.

Output:

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

If you ever need a zip that takes the longest list, itertools.zip_longest(..) can be used, it takes a default param that is substituted for any shorter list-items that are not there.

Btw. just list(zip(l)) looks like this: [(1,5,9),(2,6,10),(3,7,11),(4,8,12)] - it create tuples over the same indexes of the parts of the iterable you put into it.


By hand:

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


l2 = []
for colIdx in range(len(l[0])):  # 0-3 iterate over the inner indexes first
    newRow = []
    for rowIdx in range(len(l)): # 0-2 then over the outer ones 
        newRow.append(l[rowIdx][colIdx])
    l2.append(newRow)

print(l2)  # [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Sign up to request clarification or add additional context in comments.

11 Comments

Is there a way to do it without built in functions? I think I'm not expected to do it with them. I dont quite understand Ubdus Samad's solution too
actually reading the comments made me think of simply applying a list comprehension instead of multiplication to get the size of list I want, then my code works. Could mutability of lists be a cause for repeated referencing? ( haven't rlly tried making a transpose function in tuple form, so food for thought) My code: def transpose(matrix): new_matrix=[[] for i in range(len(matrix[0]))] for row in matrix: i=0 for j in row: new_matrix[i]+=[j] i+=1 return new_matrix
@PrashinJeevaganth Learn the built-ins and list comprehensions, they make python fun. Edited answer for a "by hand" solution. Use a debugger to step through it to understand it. Read: how-to-debug-small-programs
@PrashinJeevaganth The multiplication is what messes your code up this time, list comp is "a" solution - but still far longer then the zip() one
is there a way to learn the built in function? Dont understand what I'm reading by looking at help(zip) for eg
|
1

What i meant was something like this:

def t(array): #The original array has size mxn
    duplicate = [[0 for x in range(len(array))] for y in range(len(array[1]))] #You create an array of size nxm, which is filled with zeros
    for i in range(len(array)): #Loop over the rows
        for j in range(len(array[i])): #Then loop over the columns
            duplicate[j][i] = array[i][j] #Replace j,i or duplicate with i,j th element of original
    return duplicate

Now,

>>> t([[ 1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.