1

I have array [1,2,1,2,3,4,3,4,1,2]

I want to loop it x times, each times moving array every element 1 position forward:

So next loop will be:

2.[2,1,2,3,4,3,4,1,2,1]

3. [1,2,3,4,3,4,1,2,1,2]

etc....

How can I manipulate array like this way?

EDIT:

What I thought, but maybe some better tricks:

Just go over the array with while loop and create new array with for cycle.

for i in range(11)
    array[i] = array[i-1]

etc etc..its pseudo code

Jaanus
  • 16,161
  • 49
  • 147
  • 202
  • sounds like HW? You have to try to learn! :) – Jeffrey Kevin Pry Sep 28 '12 at 19:00
  • @JeffreyKevinPry no I just develop all stuff, look my other questions, I am just like to learn new stuff. – Jaanus Sep 28 '12 at 19:00
  • Your loop won't work, because by the time you try to give a[1] the value of a[0], the old value of a[0] has already been overwritten with the value of a[-1], so you wind up with the whole array being copies of the last element. – Mark Reed Sep 28 '12 at 19:07
  • 1
    possible duplicate of [Efficient way to shift a list in python](http://stackoverflow.com/questions/2150108/efficient-way-to-shift-a-list-in-python) – Martijn Pieters Sep 28 '12 at 19:09

4 Answers4

5

Using a List data structure isn't an efficient way to do this. A Queue would be more appropriate. In any case:

Using a Queue

As I suggested, using a Queue (collections.deque):

>>> q = collections.deque([1,2,3,4,5,6,7,8])
>>> for _ in xrange(5):
...     q.rotate(-1)
... 
>>> q
deque([6, 7, 8, 1, 2, 3, 4, 5])

Keeping the List

>>> a = [1,2,3,4,5,6,7,8]
>>> for _ in xrange(5):
...     a = a[1:] + a[:1]
... 
>>> a
[6, 7, 8, 1, 2, 3, 4, 5]

Alternatively (faster than the previous one):

>>> a = [1,2,3,4,5,6,7,8]
>>> for _ in xrange(5):
...     a.append(a.pop(0))
... 
>>> a
[6, 7, 8, 1, 2, 3, 4, 5]

Here you can change xrange for whatever you want to iterate over.

Timeit analysis:

Pop-Append

>>> timeit.timeit('a.append(a.pop(0))', setup='a = [0,1,2,3,4,5,6,7,8,9]', number=1000000)
0.24548697471618652
>>> timeit.timeit('a.append(a.pop(0))', setup='a = [0,1,2,3,4,5,6,7,8,9]', number=100000000)
23.65538215637207

Slicing

>>> timeit.timeit('a=a[1:] + a[:1]', setup='a = [0,1,2,3,4,5,6,7,8,9]', number=1000000)
0.36037278175354004
>>> timeit.timeit('a=a[1:] + a[:1]', setup='a = [0,1,2,3,4,5,6,7,8,9]', number=100000000)
35.06173801422119

Queue

>>> timeit.timeit('q.rotate(-1)', setup='import collections; q = collections.deque([0,1,2,3,4,5,6,7,8])', number=1000000)
0.16829514503479004
>>> timeit.timeit('q.rotate(-1)', setup='import collections; q = collections.deque([0,1,2,3,4,5,6,7,8])', number=100000000)
16.012277841567993

With a little optimization, basically removing the __getattr__ call for append, pop and rotate:

Pop-Append

>>> timeit.timeit('aa(ap(0))', setup='a = [0,1,2,3,4,5,6,7,8,9]; aa=a.append; ap=a.pop', number=1000000)
0.15255093574523926
>>> timeit.timeit('aa(ap(0))', setup='a = [0,1,2,3,4,5,6,7,8,9]; aa=a.append; ap=a.pop', number=100000000)
14.50795292854309

Queue

>>> timeit.timeit('r(-1)', setup='import collections; q = collections.deque([0,1,2,3,4,5,6,7,8]); r=q.rotate', number=1000000)
0.13374090194702148
>>> timeit.timeit('r(-1)', setup='import collections; q = collections.deque([0,1,2,3,4,5,6,7,8]); r=q.rotate', number=100000000)
11.435136079788208
Lewis Diamond
  • 23,164
  • 2
  • 24
  • 32
4

I would use a deque because it has the built in method rotate:

import collections

d = collections.deque([1,2,1,2,3,4,3,4,1,2])
for _ in xrange(number_of_shifts):
    d.rotate(-1)
    print list(d)
halex
  • 16,253
  • 5
  • 58
  • 67
1
my_list = [1,2,1,2,3,4,3,4,1,2]
for i in range(10):
    my_list.insert(0,my_list.pop())
    print my_list
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
0

You question finds its answer in this question (which answers help in improving ...) Efficient way to shift a list in python

To make it short, make a function to shift your array:

def shift(l, n):
   return l[n:] + l[:n]

Then call this function in a loop:

myarray=[1,2,3,4,5,6,7]
for ii in range(10):
   myarray=shift(myarray, 1)
   print myarray
Community
  • 1
  • 1
Bruno von Paris
  • 882
  • 1
  • 7
  • 26