I'm new to coding and am trying to write a simple code that will take a list, say [1,2,3] and cycle the elements n number of times. So if n=1, I should get A=[3,1,2]. If n=2, I should get A=[2,3,1].The code I have written is:
n=1
j=0
A = [1,2,3]
B = [None]*len(A)
while j<=n:
for i in range(0,len(A)):
B[i] = A[-1+i]
j=j+1
print(B)
The problem is that no matter what the value of n is I get the same answer which is only cycled once. I think the problem is that the loop is cycling through the same B every time, so I need to store the new B as something else and then repeat the loop with new B. But I can't figure out how to do that. Any tips would be appreciated
I think you're overcomplicating it. Consider changing it to something like the following:
n = 1
A = [1,2,3]
B = A.copy()
for _ in range(n):
# Cycle through by concatenating the last element and all other elements together
B = [B[-1]]+B[0:-1]
print(B)
In case of n=1
, you get [3, 1, 2]
, and n=2
gives you [2, 3, 1]
Note that what you are trying to do is implemented in numpy.roll
(I suppose you're asking about the process, not the result, but just in case)
import numpy as np
>>> np.roll(A,1)
array([3, 1, 2])
>>> np.roll(A,2)
array([2, 3, 1])
A simpler function for this is:
def roll(L, n):
n %= len(L)
return L[-n:] + L[:-n]
A = [1,2,3]
roll(A, 1) # [3, 1, 2]
roll(A, 2) # [2, 3, 1]
roll(A, 3) # [1, 2, 3]
roll(A, 4) # [3, 1, 2]
Taking the modulus (n %= len(L)
) avoids the need to keep cycling through. We then just concatenate an appropriate-sized slice off the end of the list to the beginning of it.
See @sacul's answer for the problem with your code. But list
is not the most appropriate structure for such a requirement as each shift has O(n) complexity.
deque
("double-ended queue") from the collections
module provides this feature via its rotate
method. This method works in-place and has O(k) complexity, where k is argument representing the number of rotations. Here's an example:
from collections import deque
d = deque([1,2,3])
d.rotate(2)
print(d)
deque([2, 3, 1])
@sacul's answer works, but you were close! You missed updating A
for the next iteration of the while loop after you created your new B
.
n=1
j=0
A = [1,2,3]
B = [None]*len(A)
while j<=n:
for i in range(0,len(A)):
B[i] = A[-1+i]
A = B[:] # update A so that next time B works on the new A
print('A is now ', A) # to debug
j=j+1
print(B)
This results in the following print statements:
A is now [3, 1, 2]
A is now [2, 3, 1]
[2, 3, 1] # this is what finally B is
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With