2

I understand this question has been asked before but I haven't seen any that answer it in a way without splitting the list.

say I have a list:

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

I want to create a function:

rotate(lst, x):

So that if I call rotate(num, 3) it will globally edit the list num. That way when I later call print(num) it will result in [4,5,6,1,2,3].

I understand that I could write the function something like:

rotate(lst, x):
    return [lst[-x:] + lst[:-x]

But I need to do this function without a return statement, and without splitting the list. What I'm thinking would work would be to put the last value of the list into a variable: q = lst[-1] and then from there create a loop that runs x amount of times that continues to move the values towards the end of the list and replacing the 0th position with whatever is stored in q.

One more thing. If I call rotate(lst, -3) then instead of rotating to the "right" it would have to rotate to the "left".

I'm new to python and having trouble wrapping my mind around this concept of manipulating lists. Thank you everyone for your time and effort. I hope this problem was clear enough.

3
  • 4
    rather than "globally edit the list", people usually say "edit the list in place" Commented Nov 5, 2015 at 20:57
  • You might find this interesting: stackoverflow.com/questions/23321216/… Commented Nov 5, 2015 at 21:01
  • Oh thanks! Always helps to be updated on the jargon. :) Commented Nov 5, 2015 at 21:36

6 Answers 6

6

You can use slicing assignment to modify your current strategy to do what you want. You're already generating the rotated list correctly, just modify the list in place with lst[:] = ...

def rotate(lst, x):
    lst[:] =  lst[-x:] + lst[:-x]

Example in the interactive interpreter:

>>> l = [1, 2, 3, 4, 5, 6]
>>> def rotate(lst, x):
...     lst[:] =  lst[-x:] + lst[:-x]
...
>>> rotate(l, 2)
>>> l
[5, 6, 1, 2, 3, 4]

Now rotate it backwards:

>>> rotate(l, -2)
>>> l
[1, 2, 3, 4, 5, 6]
>>> rotate(l, -2)
>>> l
[3, 4, 5, 6, 1, 2]

See this answer on a different question: https://stackoverflow.com/a/10623383/3022310

Sign up to request clarification or add additional context in comments.

4 Comments

alright, but wasn't without a return statement, and without splitting the list. a requirement?
Hrm... I can see how without splitting the list could mean no use of the slicing operator permitted but that's not how I first read it.
Yeah, so this solution works fine without the return statement, but it splits the list. Is there a way to do this without splitting? Sorry, splitting, slicing... I'm new to this :/
Yeah I'd probably defer to one of the other answers that have sprung up.
3

Here is a solution using a double-ended queue. As required, it modifies the list in place, neither uses return nor uses chunks of the list.

from collections import deque

def rotate(lst, x):
    d = deque(lst)
    d.rotate(x)
    lst[:] = d

num = [1,2,3,4,5,6]
rotate(num,3)
print(num)
rotate(num,-3)
print(num)

produces

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

Please have a look at PMOTW's tutorial on deque

1 Comment

@rofls I had just looked at the example, thank you for pointing that out. Edited.
1
def rotate(lst, num):
    copy = list(lst)
    for (i, val) in enumerate(lst):
      lst[i] = copy[i - num]

Comments

0

Try:

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

def rotate(lst,x):
    copy = list(lst)
    for i in range(len(lst)):
        if x<0:
            lst[i+x] = copy[i]
        else:
            lst[i] = copy[i-x]

rotate(num, 2)

print num

Comments

0

Here is a simple method using pop and insert on the list.

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

def rotate(lst, x):
    if x >= 0:
        for i in range(x):
            lastNum = lst.pop(-1)
            lst.insert(0, lastNum)

    else:
        for i in range(abs(x)):
            firstNum = lst.pop(0)
            lst.append(firstNum)

    return

print num #[1, 2, 3, 4, 5, 6]
rotate(num, 2)
print num #[5, 6, 1, 2, 3, 4]
rotate(num, -2)
print num #[1, 2, 3, 4, 5, 6]

Comments

0

I believe this satisfies all requirements. The idea is from the book Programming Pearls by Jon Bentley. To rotate a list we can reverse it and then reverse sublists with the rotating index as pivot.

def rotate(num, rot):
    if rot < 0:
        rot = len(num) + rot
    rot = rot - 1
    num.reverse()
    for i in range(rot/2 + 1):
        num[i], num[rot-i] = num[rot-i], num[i]
    for i in range(1, (len(num) - rot)/2):
        num[rot+ i], num[len(num) - i] = num[len(num) - i], num[rot+ i]

#Testing...
num = range(1, 10)
rot = -1
print num
rotate(num, rot)
print num

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.