what is the most efficient way to turn a list in python

Question:

so I have this list in python,

a=  [[1,2,3,4],
     [2,4,5,1],
     [3,4,6,2],
     [2,3,4,5]]

and want to turn the list reading horizontally to vertically.

b=    [[1,2,3,2],
       [2,4,4,3],
       [3,5,6,4],
       [4,1,2,5]]

what is the best way to do it, and most efficient way to do it? i’m pretty new to programming, sorry for being noob. thanks.

Asked By: tipsywacky

||

Answers:

You can do it like that:

zip(*your_list)

Proof:

>>> a = [[1, 2, 3, 4], [2, 4, 5, 1], [3, 4, 6, 2], [2, 3, 4, 5]]
>>> zip(*a)
[(1, 2, 3, 2), (2, 4, 4, 3), (3, 5, 6, 4), (4, 1, 2, 5)]
Answered By: Tadeck

Check out numpy library. You can put your list into an array and transpose it like this:

a = array ([[1,2,3,4],
       [2,4,5,1],
       [3,4,6,2],
       [2,3,4,5]])
a.transpose()

P.S.: Explanation of Tadeck‘s solution is very easy. zip has the following signature:

zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

So, it takes a number of sequences (we don’t know how much exactly) and then builds tuples in the following order: takes first element of every sequence ant puts them in the tuple, then takes second element of every sequence and puts them in the second tuple and so on. It returns list of all tuples it build during its execution.

*lst – is, in fact, unpacking of arguments list. You can read more about it in the following note.

I hope, now everyone understands how this pretty piece of code works. 🙂

Answered By: aga

Another way is:

a=  [[1,2,3,4],
     [2,4,5,1],
     [3,4,6,2],
     [2,3,4,5]]
a = [[row[i] for row in a] for i in range(len(a[0]))]
Answered By: Sufian Latif

You asked about efficiency. You can use timeit for that.

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]" "zip(*a)"
1000000 loops, best of 3: 0.569 usec per loop

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]" "map(None, *a)"
1000000 loops, best of 3: 0.644 usec per loop    

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]" "[[row[i] for row in a] for i in xrange(len(a[0]))]"
1000000 loops, best of 3: 1.43 usec per loop    

>python -m timeit -s "from numpy import array; a = array([[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]])" "a.transpose()"
1000000 loops, best of 3: 0.249 usec per loop

For a large data set of [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]*1000000

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]*1000000" "zip(*a)"
10 loops, best of 3: 400 msec per loop

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]*1000000" "map(None, *a)"
10 loops, best of 3: 458 msec per loop

>python -m timeit -s "a = [[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]*1000000" "[[row[i] for row in a] for i in xrange(len(a[0]))]"
10 loops, best of 3: 770 msec per loop

>python -m timeit -s "from numpy import array; a = array([[1,2,3,4],[2,4,5,1],[3,4,6,2],[2,3,4,5]]*1000000)" "a.transpose()"
1000000 loops, best of 3: 0.251 usec per loop

If your lists are of different lengths, zip truncates to the shortest length. You can use ‘map’ or itertools.izip_longest to instead fill the missing values with None.

Answered By: jmilloy
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.