Python Array Rotation

前端 未结 7 1256
夕颜
夕颜 2020-12-03 08:24

So I am implementing a block swap algorithm in python.

The algorithm I am following is this:

Initialize A = arr[0..d-1] and B = arr[d..n-1] 1) Do following u

相关标签:
7条回答
  • 2020-12-03 08:25

    A simple and shorthand syntax for array rotation in Python is

    arr = arr[numOfRotations:]+arr[:numOfRotations]
    

    Example:

    arr = [1,2,3,4,5]
    rotations = 4
    then 
    
    arr = arr[4:]+arr[:4]
    

    gives us

    [5,1,2,3,4]

    0 讨论(0)
  • 2020-12-03 08:30

    I expect that when you pass a slice of a to your recursive call, you're not passing the same variable any more. Try passing a in its entirety and the upper / lower bounds of your slice as additional arguments to your function.

    For instance consider this function:

    def silly(z):
      z[0] = 2
    

    I just tried the following:

    >>> z = [9,9,9,9,9,9]
    >>> silly(z)
    >>> z
    [2, 9, 9, 9, 9, 9]
    >>> silly(z[3:])
    >>> z
    [2, 9, 9, 9, 9, 9]
    

    Where you can see the modification to the slice was not retained by the full array

    Out of curiosity, what outputs do you get & what outputs do you expect?

    0 讨论(0)
  • 2020-12-03 08:32

    I found a problem that I needed Right and Left rotations for big values of k (where k is number of rotations), so, I implemented the following functions for any size of k.

    Right Circular Rotation (left to the right: 1234 -> 4123):

    def right_rotation(a, k):
       # if the size of k > len(a), rotate only necessary with
       # module of the division
       rotations = k % len(a)
       return a[-rotations:] + a[:-rotations]
    

    Left Circular Rotation (right to the left: 1234 -> 2341):

    def left_rotation(a, k):
       # if the size of k > len(a), rotate only necessary with
       # module of the division
       rotations = k % len(a)
       return a[rotations:] + a[:rotations]
    

    Sources:

    • https://stackoverflow.com/a/46846544/7468664
    • https://stackoverflow.com/a/9457923/7468664
    0 讨论(0)
  • 2020-12-03 08:32

    Do you actually need to implement the block swap or are you just looking to rotate the array? In python you can do CW and CWW rotations using

    zip(*arr[::-1])
    

    and

    zip(*arr)[::-1]
    
    0 讨论(0)
  • 2020-12-03 08:34
    def leftRotation():
        
        li = [int(x) for x in input().split()]
    
        d = int(input())
        ans = (li[d:]+li[0:d])
    
        for i in ans:
            print(i,end=' ')
        print()
        
    leftRotation()
    
    0 讨论(0)
  • 2020-12-03 08:37

    You can rotate a list in place in Python by using a deque:

    >>> from collections import deque
    >>> d=deque([1,2,3,4,5])
    >>> d
    deque([1, 2, 3, 4, 5])
    >>> d.rotate(2)
    >>> d
    deque([4, 5, 1, 2, 3])
    >>> d.rotate(-2)
    >>> d
    deque([1, 2, 3, 4, 5])
    

    Or with list slices:

    >>> li=[1,2,3,4,5]
    >>> li[2:]+li[:2]
    [3, 4, 5, 1, 2]
    >>> li[-2:]+li[:-2]
    [4, 5, 1, 2, 3]
    

    Note that the sign convention is opposite with deque.rotate vs slices.

    If you want a function that has the same sign convention:

    def rotate(l, y=1):
       if len(l) == 0:
          return l
       y = -y % len(l)     # flip rotation direction
       return l[y:] + l[:y]
    
    >>> rotate([1,2,3,4,5],2)
    [4, 5, 1, 2, 3]
    >>> rotate([1,2,3,4,5],-22)
    [3, 4, 5, 1, 2]
    >>> rotate('abcdefg',3)
    'efgabcd'
    

    For numpy, just use np.roll

    >>> a
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> np.roll(a, 1)
    array([9, 0, 1, 2, 3, 4, 5, 6, 7, 8])
    >>> np.roll(a, -1)
    array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
    

    Or you can use a numpy version of the same rotate above (again noting the difference in sign vs np.roll):

    def rotate(a,n=1):
        if len(a) == 0:
            return a
        n = -n % len(a)     # flip rotation direction
        return np.concatenate((a[n:],a[:n]))  
    
    0 讨论(0)
提交回复
热议问题