Python standard library for reordering a list

I am wondering if there is a standard library function in Python that will order list items, as shown below:

a = [1,2,3,4,5,6,7] function(a) print a a = [1,7,2,6,3,5,4] 

It should receive one element from the beginning of the original list, then from the end, then from the beginning and so on. Then change the list.

Hi,

+7
source share
5 answers

You can quickly create an efficient memory generator using itertools , which does what you want:

 from itertools import chain, izip def reorder(a): gen = chain.from_iterable(izip(a, reversed(a))) for _ in a: yield next(gen) >>> list(reorder(a)) <<< [1, 7, 2, 6, 3, 5, 4] 

You will find that itertools has an excellent collection of building blocks to create your own efficient iterators. A slightly more concise solution:

 >>> list(chain.from_iterable(izip(a, reversed(a))))[:len(a)] <<< [1, 7, 2, 6, 3, 5, 4] 

List comprehensions is another very concise way to create lists:

 >>> [x for t in zip(a, reversed(a)) for x in t][:len(a)] <<< [1, 7, 2, 6, 3, 5, 4] 

Finally, here's a short single-line letter just for fun:

 >>> sum(zip(a, a[::-1]), ())[:len(a)] <<< (1, 7, 2, 6, 3, 5, 4) 
+9
source
 >>> ((a+a[:0:-1])*len(a))[::len(a)][:len(a)] [1, 7, 2, 6, 3, 5, 4] 
+3
source
 for a in ([1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8], [1,2,3,4], [1,2,3], [1,2,], [1], []): print a [ a.insert(i,a.pop()) for i in xrange(1,len(a)+1,2)] print a,'\n' 

result

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

Update 1

Comparison with zeekay code:

 from time import clock n = 100000 te = clock() for i in xrange(n): a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] [ a.insert(i,a.pop()) for i in xrange(1,len(a)+1,2)] print clock()-te from itertools import chain, izip def reorder(a): gen = chain(*izip(a, reversed(a))) for _ in a: yield next(gen) te = clock() for i in xrange(n): a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] a = list(reorder(a)) print clock()-te 

result

 2.36667984339 5.00051766356 

My method changes a in place

+2
source

Of course, in Python there is only one way to do something :-):

 def function(a): ret = [] this_end, other_end = 0, -1 while a: ret.append(a.pop(this_end)) this_end, other_end = other_end, this_end return ret a = [1,2,3,4,5,6,7] print function(a) 

For timings:

 % python -m timeit 'def function(a): quote> ret = [] quote> this_end, other_end = 0, -1 quote> while a: quote> ret.append(a.pop(this_end)) quote> this_end, other_end = other_end, this_end quote> return ret quote> quote> a = [1,2,3,4,5,6,7] quote> quote> print function(a) quote> ' | tail [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] [1, 7, 2, 6, 3, 5, 4] 100000 loops, best of 3: 10.5 usec per loop 
+2
source

Thanks, I wrote my own function:

 def shake(list): """Gets a list and reorders the items, one from beginning, one from end""" #print "original list is: ", list new_list = [] x = len(list) - 1 y = len(list)/2 for i in xrange(y): if list[i] not in new_list: new_list.append(list[i]) if list[i+x] not in new_list: new_list.append(list[i+x]) x -= 2 if len(list)%2 == 1: new_list.append(list[y]) #print "new list is: ", new_list return new_list 
+1
source

All Articles