Reputation: 854
Hello I have a sorted list ['a','b','c','d','e','f']
that is currently displayed on the front end as the matrix
['a','c','e'],
['b,'d','f'],
When it should be
['a','b','c'],
['d,'e','f'],
Unfortunately I'm not able to modify the front end to display the object horizontally so I would like to be able to rearrange the 1d array into another 1d array with the correct order ['a','d','b','e','c',f']
.
I conceptually know how it could be done by converting the 1d array into a 2d array, then rotating the matrix, then converting the 2d array back into a 1d array. However I was wondering if there is a more pythonic way/faster general algorithm for achieving this.
Upvotes: 0
Views: 406
Reputation: 2545
numpy
I believe the most efficient, considering that you are talking about a GUI and GUI tend to change in size, would be to use numpy
to implement your own proposal:
a = np.array(['a','b','c','d','e','f'])
n = len(a)
a.reshape(2, int(n)/2).T.reshape(1,n)
The output is:
array([['a', 'd', 'b', 'e', 'c', 'f']], dtype='<U1')
Using the solution from the answer of wim:
%timeit [*L[0::3], *L[1::3], *L[2::3]]
>>> 559 ns ± 18 ns per loop
%timeit np.array(L).reshape(2,3).T.reshape(1,6).tolist()
>>> 5.01 µs ± 257 ns per loop
a = np.array(L)
%timeit L.reshape(2,3).T.reshape(1,6)
>>> 1.58 µs ± 84.1 ns per loop
n = int(len(L)/2)
%timeit [j for i in range(n) for j in L[i::n]]
>>> 1.31 µs ± 73.3 ns
It seems that, for constant sizes, wim answer with slicing is best, followed by slicing with list comprehension when the size is not known beforehand.
Upvotes: 1
Reputation: 362497
Stride it with slices:
>>> L = ['a','b','c','d','e','f']
>>> [*L[0::3], *L[1::3], *L[2::3]]
['a', 'd', 'b', 'e', 'c', 'f']
Consider using numpy if you need to generalise this to arbitrary dimensions:
>>> np.array(L).reshape(2,3).T.ravel().tolist()
['a', 'd', 'b', 'e', 'c', 'f']
Upvotes: 2