Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python move all elements of a list to the right by one [duplicate]

So I want to move all the elements to the right so for example if I had a list of [1, 2, 3, 4, 5] it would become [5, 1, 2, 3, 4]. So basically the rightmost element wraps around to the leftmost element and the other elements basically shift the right.

Here is my code:

length = len(values)
old_right = values[length - 1]
for j in range(length - 1, 0, -1):
    values[j] = values[j - 1]
values[0] = old_right

When i enter it in idle i get an error on the last line on values[0] (highlighted on values) saying SyntaxError: invalid syntax. I do not know why I get this error.

Also, how would I have to change my code to make it go from [5, 4, 3, 2, 1] back to [1, 2, 3, 4, 5], i.e. reverse the process?

like image 556
JerryMichaels Avatar asked Dec 15 '15 00:12

JerryMichaels


2 Answers

>>> lst = [1, 2, 3, 4, 5]
>>> [lst[-1]] + lst[:-1]
[5, 1, 2, 3, 4]

reverse:

>>> lst = [5, 1, 2, 3, 4]
>>> lst[1:] + [lst[0]]
[1, 2, 3, 4, 5]

edit:

I used [1, 2, 3, 4, 5] as an example, but i wrote the code for it to work on any list no matter what it is it would take the rightmost value of the list to the left. In your case this does work but only if you assign the specific list. I am wondering how would you do it so it works any general case.

Then write a function.

def shift_right(lst):
    try:
        return [lst[-1]] + lst[:-1]
    except IndexError:
        return lst
like image 192
timgeb Avatar answered Nov 15 '22 06:11

timgeb


Use the deque module.

from collections import deque
a = deque([1,2,3,4,5]).rotate(1)

a = list(a)

This is the ideal solution since it lets you rotate the list an arbitrary number of places. If you want to rotate it the other way, you can make the argument to rotate negative.

EDIT:

The currently accepted answer is much slower than this approach. The deque data structure is optimized for inserting at the beginning of the list and the end of the list, which is much faster than the linear time operation of the accepted answer. This may not matter in the context for which the OP is using the code, but in any context where performance matters, deque is the way to go.

I wrote a small program that rotates a list of 1,000,000 elements by one position 1,000 times. Here are the results

List Slicing: 0:00:12.043186
Deque: 0:00:00.028064

Code is here.

import datetime
from collections import deque


start = datetime.datetime.now()

lst = [1]* 1000000

#first approach
for x in range(1000):
    lst = [lst[-1]] + lst[:-1]

end  = datetime.datetime.now()
print end - start

lst = deque(lst)
#second approach 
for y in range(1000):
    lst.rotate(1)
lst = list(lst)

start = datetime.datetime.now()
print start - end
like image 35
Erik Godard Avatar answered Nov 15 '22 06:11

Erik Godard