Python List Rotation

Efficient way to rotate a list in python

A collections.deque is optimized for pulling and pushing on both ends. They even have a dedicated rotate() method.

from collections import deque
items = deque([1, 2])
items.append(3) # deque == [1, 2, 3]
items.rotate(1) # The deque is now: [3, 1, 2]
items.rotate(-1) # Returns deque to original state: [1, 2, 3]
item = items.popleft() # deque == [2, 3]

How to rotate a Python list to centre a specific value

The rotation point needs to be computed based on the index of the value and the length of the list, since you want to rotate into the middle we subtract (len(lst)-1)//2 from the index and take the modulus relative to the length to find the rotation point:

lst = [1, 2, 3, 4, 5]
l = len(lst)

for n in lst:
i = lst.index(n)
r = (i-(l-1)//2) % l
out = lst[r:] + lst[:r]
print(out)

Output:

[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]

List rotation of first element in the list and moving it to the end using python

Use this code:

def rotatelist(l, k):
n = len(l)
if k < 0:
return l
d=l
while(k>0):
temp=d[0]
for i in range(n-1):
d[i]=d[i+1]
d[i+1]=temp
k=k-1
return d

rotating a list to the right by k times

Since on this case rotating by 7 have the same effect as rotating by 1 you have to use the modulus operator on the len of the list. You can also simplify the code by using slice notation:

def rotate(l, num):
num = num % len(l)
return l[num:] + l[:num]

Note: Don't override built-in reserved words

How can I rotate a list right and left?

First you could use print() and test it for different values

def rotate(l, r):
return l[r:] + l[:r]

l = ['A','B','C','D',1,2,3,4,5]

print('len(l):', len(l))

for r in range(0, -34, -1):
print(f"{r:3}", rotate(l, r))

And you see

len(l): 9
0 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-1 [5, 'A', 'B', 'C', 'D', 1, 2, 3, 4]
-2 [4, 5, 'A', 'B', 'C', 'D', 1, 2, 3]
-3 [3, 4, 5, 'A', 'B', 'C', 'D', 1, 2]
-4 [2, 3, 4, 5, 'A', 'B', 'C', 'D', 1]
-5 [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D']
-6 ['D', 1, 2, 3, 4, 5, 'A', 'B', 'C']
-7 ['C', 'D', 1, 2, 3, 4, 5, 'A', 'B']
-8 ['B', 'C', 'D', 1, 2, 3, 4, 5, 'A']
-9 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-10 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-11 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-12 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-13 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-14 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-15 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-16 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-17 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-18 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-19 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-20 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-21 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-22 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-23 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-24 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-25 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-26 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-27 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-28 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-29 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-30 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-31 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-32 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-33 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]

When -r is bigger then len(r) then it doesn't work as you would expect.

It gets empty list + full list or full list + empty list

The same problem is with +34 and -34.

Because you get the same list for r=len(l), r=len(l)*2, ...r=len(l)*n so you would use modulo (r % len(l)) to have value smaller then len(l) and get what you need.

def rotate(l, r):
r = r % len(l)
return l[r:] + l[:r]

l = ['A','B','C','D',1,2,3,4,5]

print('len(l):', len(l))

for r in range(0, -34, -1):
print(f"{r:3}", rotate(l, r))

Result:

len(l): 9
0 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-1 [5, 'A', 'B', 'C', 'D', 1, 2, 3, 4]
-2 [4, 5, 'A', 'B', 'C', 'D', 1, 2, 3]
-3 [3, 4, 5, 'A', 'B', 'C', 'D', 1, 2]
-4 [2, 3, 4, 5, 'A', 'B', 'C', 'D', 1]
-5 [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D']
-6 ['D', 1, 2, 3, 4, 5, 'A', 'B', 'C']
-7 ['C', 'D', 1, 2, 3, 4, 5, 'A', 'B']
-8 ['B', 'C', 'D', 1, 2, 3, 4, 5, 'A']
-9 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-10 [5, 'A', 'B', 'C', 'D', 1, 2, 3, 4]
-11 [4, 5, 'A', 'B', 'C', 'D', 1, 2, 3]
-12 [3, 4, 5, 'A', 'B', 'C', 'D', 1, 2]
-13 [2, 3, 4, 5, 'A', 'B', 'C', 'D', 1]
-14 [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D']
-15 ['D', 1, 2, 3, 4, 5, 'A', 'B', 'C']
-16 ['C', 'D', 1, 2, 3, 4, 5, 'A', 'B']
-17 ['B', 'C', 'D', 1, 2, 3, 4, 5, 'A']
-18 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-19 [5, 'A', 'B', 'C', 'D', 1, 2, 3, 4]
-20 [4, 5, 'A', 'B', 'C', 'D', 1, 2, 3]
-21 [3, 4, 5, 'A', 'B', 'C', 'D', 1, 2]
-22 [2, 3, 4, 5, 'A', 'B', 'C', 'D', 1]
-23 [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D']
-24 ['D', 1, 2, 3, 4, 5, 'A', 'B', 'C']
-25 ['C', 'D', 1, 2, 3, 4, 5, 'A', 'B']
-26 ['B', 'C', 'D', 1, 2, 3, 4, 5, 'A']
-27 ['A', 'B', 'C', 'D', 1, 2, 3, 4, 5]
-28 [5, 'A', 'B', 'C', 'D', 1, 2, 3, 4]
-29 [4, 5, 'A', 'B', 'C', 'D', 1, 2, 3]
-30 [3, 4, 5, 'A', 'B', 'C', 'D', 1, 2]
-31 [2, 3, 4, 5, 'A', 'B', 'C', 'D', 1]
-32 [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D']
-33 ['D', 1, 2, 3, 4, 5, 'A', 'B', 'C']

BTW:

Without modulo you would have to use for-loops with [1:], [:1] or [-1:],[:-1] - but it need many moves - so it may need more time and memory (but for small list it is not visible).

def rotate(l, r):
if r >= 0:
for _ in range(0, r, 1):
l = l[1:] + l[:1]
else:
for _ in range(0, r, -1):
l = l[-1:] + l[:-1]

return l

l = ['A','B','C','D',1,2,3,4,5]

print('len(l):', len(l))

#for r in range(0, -34, -1):
# print(f"{r:3}", rotate(l, r))

for r in range(0, 34, 1):
print(f"{r:3}", rotate(l, r))

The same with one for-loop

def rotate(l, r):

if r >= 0:
s = 1
else:
s = -1

for _ in range(0, r, s):
l = l[s:] + l[:s]

return l

Cyclic Rotation of Numbers in a List in Python

Let's take a look at what happens if K = 1, on just the first iteration:

def sol(A, K):
for i in range(len(A)): # i = 0
if (i+K) < len(A): # i + 1 < 5
A[i+K] = A[i] # A[1] = A[0]
else:
A[i+K - len(A)] = A[i]
# A is now equal to [3, 3, 9, 7, 6] - the element at A[1] got overwritten
return A

The problem is that you don't have anywhere to store the elements you'd be overwriting, and you're overwriting them before rotating them. The ideal solution is to create a new list, populating it with rotated elements from the previous list, and return that. If you need to modify the old list, you can copy elements over from the new list:

def sol(A, K):
ret = []
for i in range(len(A)):
if (i + K) < len(A):
ret.append(A[i + K])
else:
ret.append(A[i + K - len(A)])
return ret

Or, more concisely (and probably how your instructor would prefer you solve it), using the modulo operator:

def sol(A, K):
return [
A[(i + K) % len(A)]
for i in range(len(A))
]

Arguably the most pythonic solution, though, is to concatenate two list slices, moving the part of the list after index K to the front:

def sol(A, K):
return A[K % len(A):] + A[:K % len(A)]

Rotate array to left k cells python

Every time you're trying to shift consecutive items from the source array, you're overwriting the first item source[i] with the second one source[i+k] without first saving the value from source[i].

Solution:

def shiftLeft(source, k):
length = len(source)
i = 0

while(i < (length - k)):
start = source[i]
source[i] = source[i+k]
source[i+k] = start
i += 1

source=[10,20,30,40,50,60]
a = shiftLeft(source, 2)
print(source)

program to rotate list of numbers until all numbers have moved back to origional position

You can use the input function to get user input. The input would be a string so you would then have to split it using str.split method to create a list from the input.

like this:

user_input = input("Input a list: ")  # input = '1 2 3 4'
seq = user_input.split() # seq = ['1','2','3','4']

def rotation(nums):
for i in range(len(nums)+1):
rotated = nums[i:] + nums[:i]
print(','.join(rotated))

rotation(seq)


Related Topics



Leave a reply



Submit