I would like to index a numpy
array with integer and half values. This is roughly what I have in mind:
>>> a = HalfIndexedArray([[0,1,2,3],[10,11,12,13],[20,21,22,23]])
>>> print(a[0,0])
0
>>> print(a[0.5,0.5])
11
>>> print(a[0,1 0.5])
3
Only half-values would be used as indices, so I imagine some kind of wrapper could be constructed that stores the values at integer indices that are accessed by multiplying the given fractional index.
One could construct some kind of helper function that can get and set the values accordingly; however, it would be even better if the native numpy indexing functionality (slices etc.) could be still used. Additionally, significant overhead is not really acceptable, as these arrays would be used for numerical computations.
It is basically some efficient syntactic sugar that I am looking for: is this something that can be achieved in numpy (or more broadly, in Python)?
Edit: To make it clearer: my goal is to use both the integer and the half indices. The whole point is to make the code cleaner, as the half-indices would correspond to half-steps during time-stepping in a numerical solver (where integer-steps also exist). E.g. see here as a simple example where fractional indices are routinely used in mathematical notation.
CodePudding user response:
In order to change behavior of []
you need to reimplement __getitem__
class method. Since your class would behave as a standard list otherwise, you can do this:
class HalfIndexedList(list):
def __getitem__(self, key):
return super().__getitem__(int(key * 2))
a = HalfIndexedList([10,11,12,13,14,15])
for i in range(0, 6):
print(f"{i/2 = }, {a[i/2] = }")
(This of course affects only getting items using []
operator, things like value returned by a.index
will be unaffected.
However, I agree with @Otto answer and the statement that it's much better to handle that input-side for cleaner code. Half-indexing doesn't make sense and is really unintuitive.
As a side note, indexing 2D array in Python is usually done using a[i][j]
, not a[i, j]
as 2D arrays are effectively lists of lists.
CodePudding user response:
My recommendation would be that instead of creating a separate class to account for half-integer indexing, just handle it on the input side. If you take a half-integer index system and multiply your input by two, you can translate that trivially to a normal integer index.
This would likely result in a cleaner and easier to upkeep piece of code.
However, if you want to go ahead and create a custom iterable, this could be helpful: https://thispointer.com/python-how-to-make-a-class-iterable-create-iterator-class-for-it/