Home > OS >  How to imitate Pythonic indexing of arrays in Julia
How to imitate Pythonic indexing of arrays in Julia

Time:01-11

I am translating a code from Python to Julia. I have the following array:

_DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

And the following line of code:

_DAYS_IN_MONTH[index] - _DAYS_IN_MONTH[index - 1]

The idea is that, if index - 1 is evaluated to -1, then we will get the last element of the array, which is exactly what we need in this case. However, this does not work in Julia. Of course, I can write something like this:

if index == 1
    _DAYS_IN_MONTH[index] - _DAYS_IN_MONTH[end]
else
    _DAYS_IN_MONTH[index] - _DAYS_IN_MONTH[index - 1]
end

But I wonder if there is a more elegant and "Julian" way of doing this.

CodePudding user response:

Effectively what you're after is a very specific case of a circular array. You achieve that with mod1. It'll "wrap around" values outside of the valid indices. It takes two arguments; the first is the value (the index to wrap) and the second is the modulus (the length of the array). In the context of indexing, you can just use that special end syntax for the modulus:

julia> [_DAYS_IN_MONTH[index] - _DAYS_IN_MONTH[mod1(index - 1, end)] for index in 1:12]
12-element Vector{Int64}:
  0
 -3
  3
 -1
  1
 -1
  1
  0
 -1
  1
 -1
  1

CodePudding user response:

Another elegant option would be using CircularArrays

julia> _DAYS_IN_MONTH = CircularVector([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]);

julia> _DAYS_IN_MONTH .- _DAYS_IN_MONTH[0:end-1]
12-element CircularVector(::Vector{Int64}):
  0
 -3
  3
 -1
  1
 -1
  1
  0
 -1
  1
 -1
  1

Or using ShiftedArrays:

julia> _DAYS_IN_MONTH .- circshift(_DAYS_IN_MONTH,1)
12-element Vector{Int64}:
  0
 -3
  3
 -1
  1
 -1
  1
  0
 -1
  1
 -1
  1

CodePudding user response:

No need for extra packages, Julia Base has this one:

_DAYS_IN_MONTH .- circshift(_DAYS_IN_MONTH,1)
  •  Tags:  
  • Related