Stéphane Henriod
Stéphane Henriod

Reputation: 121

Transposing a multi-dimensional matrix in Python with list comprehensions

I have a Python assignment where I have to transpose a multi-dimensional matrix (3x3, 4x4,5x5...) without using any for-loops but only using list comprehension.

As an example for a 2x2 matrix, we have:

a2 = [[1, 2], [3, 4]]
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

But I am not sure I really understand how it works or how to adapt it for a 3x3, 4x4, 5x5... matrix

For instance, with

a3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

I don't necessarily want you to give me the answer (still have to figure out by myself), but any hint would be very helpful!

Thanks in advance!

Upvotes: 1

Views: 2859

Answers (2)

mgilson
mgilson

Reputation: 309841

I'm pretty sure you already have it in your example...

a2 = [[1, 2], [3, 4]]  #2x2
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

a2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  #3x3
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

The object:

a3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

Is not a 2x2, or a 3x3 or a 4x4 -- It's a 2x2x2. You'll need to explain exactly what a transpose means for that data structure.

As a side note, if you don't have the list-comprehension as a constraint, using zip as proposed by Lattyware is the way you should do this -- I'm only trying to point out that your solution already works for the NxN case.

Upvotes: 6

Gareth Latty
Gareth Latty

Reputation: 88977

There is a built-in for this - the zip() function.

>>> list(zip(*[[1, 2], [3, 4]]))
[(1, 3), (2, 4)]

Note that the call to list() is to show the result, in 3.x, this produces an iterable, not a list (which is lazy, giving memory benefits). In 2.x, it returns a list anyway.

If you want to transpose the internal parts as well in an example with more nested lists, then it's relatively simple to use a list comprehension to run zip() on the sublists.

Example in 2.x for ease of reading:

>>> zip(*(zip(*part) for part in [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]))
[((1, 3), (5, 7)), ((2, 4), (6, 8))]

Upvotes: 5

Related Questions