2

Say I have:

a = [[1, 1, 1, 6], [0, 2, -1, 3], [4, 0, 10, 42]]

and I want to transpose it to:

a = [[1,0,4], [1,2,0], [1,-1,10], [6,3,42]]

using loops in python. The current code that I have is:

def transpose(a):
    s = []
    for row in range(len(a)):
        for col in range(len(a)):
            s = s + [a[col][row]]
return s

But this gives me the output of:

[1, 0, 4, 1, 2, 0, 1, -1, 10]

Instead of this:

[[1,0,4], [1,2,0], [1,-1,10], [6,3,42]]

Can anyone help me? I'm still new at this stuff and don't understand why it doesn't work. Thanks so much!

0

3 Answers 3

1

Use zip()

>>> a = [[1, 1, 1, 6], [0, 2, -1, 3], [4, 0, 10, 42]]
>>> [list(x) for x in zip(*a)]
[[1, 0, 4], [1, 2, 0], [1, -1, 10], [6, 3, 42]]

zip(*a) unpacks the three sub-lists in a and combines them element by element. Meaning, the first elements of the each of the three sub-lists are combined together, the second elements are combined together and so on. But zip() returns tuples instead of lists like you want in your output. Like this:

>>> zip(*a)
[(1, 0, 4), (1, 2, 0), (1, -1, 10), (6, 3, 42)]

[list(x) for x in zip(*a)] converts each of the tuples to lists giving the output the way you need it.

Sign up to request clarification or add additional context in comments.

2 Comments

I know that's one way to do it, but is there another way to do this using for loops or while loops?
The other answer addresses your question. You are seeing one list in your output because you aren't creating a list in the inner loop.
1

Here is a solution that is based on your code:

def transpose(a):
    s = []
    # We need to assume that each inner list has the same size for this to work
    size = len(a[0])
    for col in range(size):
        inner = []
        for row in range(len(a)):
            inner.append(a[row][col])
        s.append(inner)
    return s

If you define an inner list for the inner loop, your output is this:

[[1, 0, 4], [1, 2, 0], [1, -1, 10], [6, 3, 42]]

3 Comments

Instead of inner.append and s.append, inner = inner + [a[row][col]] and s = s + [inner] works the same way! Thank you!!
I wouldn't say that it works exactly the same way - you might want to have a look at this helpful answer that explains the differences.
@Catury: It does not work the same way. When you do list = list + [l], it creates a new list with the value of list and l, and assign new list to list. where as list.append(l) appends l to existing list list
0

If you are looking for a solution without any fancy function. You may achieve it using list comprehension as:

>>> a = [[1, 1, 1, 6], [0, 2, -1, 3], [4, 0, 10, 42]]
>>> sublist_size = len(a[0])
>>> [[item[i] for item in a] for i in range(sublist_size)]
[[1, 0, 4], [1, 2, 0], [1, -1, 10], [6, 3, 42]]

However, simplest way is by using zip():

>>> list(zip(*a))  # for Python 3, OR, just zip(*a) in Python 2 
[(1, 0, 4), (1, 2, 0), (1, -1, 10), (6, 3, 42)]

3 Comments

Slightly shorter b = [[i[j] for i in a] for j in range(len(a)+1)]
@JackTheCrab: It is not necessary that sublist's length will be 1 more that the list's length (even though in this example). So range(len(a[0])) should be used instead of range(len(a) + 1). By nesting the two steps and shortening the variable name to decrease one line of code; It is not good practice. Shorter is not always good. If bigger (to very little extent) code is more readable, go for bigger ;)
You're right, thanks for pointing it out. Definetely agree on readability as well;)

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.