Amir Chazan
Amir Chazan

Reputation: 183

Rotating a list without using collection.deque

I want to make a script. The program should get some list L with values, and natural number N.
If N>0, the list's objects move N steps to left.
If N<0, the list's objects move abs(N) to the right.
If N=0 the list remain the same...

For example: For N=1 and L=[1,2,3,4,5], the output is [2,3,4,5,1].
For same list and N=-1 the output is [5,1,2,3,4]

I actually did it using collection.deque, but I want to do this with nothing but lists, for loop and 'if'.

I have problem to understand how to make the objects move.

l = input("enter list:")
N = input("enter number of rotations:")
import collections
d = collections.deque(l)
d.rotate(-N)
print d

Upvotes: 7

Views: 1055

Answers (6)

Eugene Yarmash
Eugene Yarmash

Reputation: 149796

You can use list slicing:

def rotate(L, N):
    if not L or N % len(L) == 0:
        return L
    return L[N % len(L):] + L[:N % len(L)]

L = [1, 2, 3, 4, 5]

for N in range(-3, 4):
    print(rotate(L, N))

Output:

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

Note that if you use a list, the time complexity of a rotation is linear to the number of elements in the list in general, since you have to move all existing elements. deque.rotate(), on the other hand, is O(k), with k being the number of steps. Therefore, if you need to rotate more than once deque.rotate() is the way to go.

Upvotes: 4

baduker
baduker

Reputation: 20042

If you're after simple lists here's how you can do it in Python 3 (based on your P2 example).

L = list(map(int, input("Enter numbers: ").split(" ")))
N = int(input("Enter how many rotations to perform: "))
print(L[N:] + L[:N])

Upvotes: 1

Amir Chazan
Amir Chazan

Reputation: 183

thank you all ! :) your answers are great and very useful for me.

here is my solution for this question (given that I do these scripts for a basic python course for biologists):

L = input('Enter list of numbers, please: ')
N = input('Enter how many places to rotate: ')
L1 = L[N:]
L2 = L[:N]
L = L1 + L2
print L

Upvotes: 0

Nras
Nras

Reputation: 4311

If using numpy is an option for you, there is a method called roll, which you might want to have a look at:

import numpy as np

array = np.arange(1, 6)  # 1 to 5
print array
print np.roll(array, 0)
print np.roll(array, 2)
print np.roll(array, -2)
print np.roll(array, 17)

The result is as expected:

[1 2 3 4 5]
[1 2 3 4 5]
[4 5 1 2 3]
[3 4 5 1 2]
[4 5 1 2 3]

Upvotes: 1

Qiang Jin
Qiang Jin

Reputation: 4467

If you don't want to create new list, you can try in-place reverse,

def reverse(nums, start, end):
    i = start
    j = end - 1
    while i < j:
        tmp = nums[i]
        nums[i] = nums[j]
        nums[j] = tmp
        i += 1
        j -= 1

def rotate(nums, n):
    if n == 0:
        return nums
    length = len(nums)
    if n < 0:
        n = length + n
    reverse(nums, 0, n)
    reverse(nums, n, length)
    reverse(nums, 0, length)
    return nums

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

Upvotes: 0

elzell
elzell

Reputation: 2306

This works:

result = l[N % len(l):]+l[:N % len(l)]

Upvotes: 2

Related Questions