Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cycling values of a list [duplicate]

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

like image 748
DeathbyGreen Avatar asked Oct 06 '18 00:10

DeathbyGreen


4 Answers

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])
like image 102
sacuL Avatar answered Oct 16 '22 21:10

sacuL


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.

like image 23
Stuart Avatar answered Oct 16 '22 21:10

Stuart


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])
like image 2
jpp Avatar answered Oct 16 '22 23:10

jpp


@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
like image 1
slider Avatar answered Oct 16 '22 23:10

slider