Tuesday, February 4, 2020

Circular shift of lists in python

Scenario

Assume I have a list in python
a = [ -2, -1, 0, 1, 2 ]
(an admittedly simple list here with integer numbers).
I want to shift these entries in the list to the left or right so that the entries moving out of the list enter the list again at the other end e.g. I want to shift 2 to the left to get this list:
[0, 1, 2, -2, -1]

Solutions

There are solutions using numpy but I want to present another easy solution just using slices.
shift = 2
x = a[shift:]       # This is [ 0, 1, 2 ]
y = a[:shift]       # This is [ -2, -1 ]
print( x + y )

[0, 1, 2, -2, -1]
I am
  • setting my shift value to 2
  • creating a slice from index 2 to the end of the list
  • creating a slice from the beginning of the list until index - 1
  • adding the two slices to get the shifted result

    This also works for negative shift values (shift to the right) which is a particularily nice feature of the pythong [:] operator.

    shift = -1
    x = a[shift:]       # This is [ 2 ]
    y = a[:shift]       # This is [ -2, -1, 0, 1 ]
    print( x + y ) 
    
    [2, -2, -1, 0, 1]
    

    Add-on: calculate the new index of a shifted element

    Starting with
    a = [ -2, -1, 0, 1, 2 ]
    
    the element -2 has index 0. The shift 2 to the left result
    [0, 1, 2, -2, -1]
    
    puts element -2 at index 3.

    How can I calculate that?

    
    def index_after_shift( old_index, shift ):
      return ( old_index - shift ) % len(a) 
    
    # Examples
    for shift in [2, -1 , 6 ]:
      for ind in [ 0,1,2,3,4]:
        print( ind, shift, index_after_shift( ind, shift ) )
      print()
    
    0 2 3
    1 2 4
    2 2 0
    3 2 1
    4 2 2
    
    0 -1 1
    1 -1 2
    2 -1 3
    3 -1 4
    4 -1 0
    
    0 6 4
    1 6 0
    2 6 1
    3 6 2
    4 6 3
    
    The function index_after_shift calculates the new index.
    A shift 2 to the left i.e. shift = 2 means that we subtract 2 from the current index to get to the new one therefore old_index - shift. This is easily understandable for indexes 2, 3, 4, ... which will become 0, 1, 2, ....
    What do we do with smaller indexes?>
    Here we are using the modulo function which will do the necessary calculation for us e.g.
    shift = 2
    old_index = 1
    # length of a is 5
    ( old_index - shift ) % len(a)
    # = ( 1 - 2 ) % 5
    # = -1 % 5
    # = 4
    
    The modulo has converted the negative number resulting from the subtraction into a positive one.

    shift to the right means we have to add something to the index to get to our new index (since the variable shift is negative for right shifts we subtract a negative number in the function which results in the addition of a positive number).

  • Thursday, January 30, 2020

    Modulo operation in programming languages - differently implemented

    Many programming languages support an operation which they call modulo operator and which is often designated by the symbol
      %
    Often it is also referred to as the remainder after division.

    Only recently I found out that this operation does not behave as one might think. The results differ depending on which programming language you are using.

    Before I go into the details I would like to illustrate the difference which shows when using negative numbers.

    Example

    I want to calculate these two expressions:
     27 % 10
    -27 % 10
    
    The result for the second expression will be different depending on the programming language.

    C

    When you are using this statement in C
    printf("%d  %d\n", 17 % 10, -17 % 10 );
    
    you get
    7  -7
    

    Python

    When you are using this statement in python
    print( '{0}  {1}'.format( 17 % 10,  -17 % 10 ) )
    
    you get
    7  3
    

    Explanation

    modulo as remainder by division

    Some programming languages implement modulo as a remainder of division operation. Thus -27 % 10 results in the leftover of -27 when you take away the maximum multiple of 10 , so you are left with -7.

    modulo as mathematically correct number

    Other programming languages implement modulo as correct in the mathematical sense.
    Mathematically modulo is defined as the number which needs to be added to a multiple of the divisor to get to the original.
    x = m % n
    There must be a number 'a' so that
    a * n + x = m
    and this condition should be met:
    0 <= x < n
    
    In our case:
    x = 3
    a = -2
    =>
    a * 10 + x = -2 * 10 + 3 = -17
    

    Conclusion

    Since I am not a programming languages expert I can only refer to the interesting Wikipedia article about modulo operations.
    This subject is worth knowing if any of your programming efforts involve some number operations.
    My personal "watch out" topic is awk programming where the behaviour is non-mathematical like C.