Here's a tricky way to do it without any loops.
def getIndex(ranges, val):
r = np.where(((ranges-val).prod(axis=1)<0) + (ranges[:,0]==val))[0]
return r[0] if len(r)!=0 else -1
I will now jokingly call this Mercury's theorem: For any range r
defined by (r_start, r_end)
, if any number n
falls within the range, then (r_start-n)
and (r_end-n)
will have opposing signs! Unless of course, n
is equal to r_start
, which leads to a non-negative 0. (n=r_end
is outside of the range)
Subtract val from ranges and take product over column axis, basically doing (r_start-n)*(r_end-n)
. This should be negative, except for the boundary case, for which we do an OR (+) with if r_starts == n
. Then we simply call np.where on the resulting boolean array. If the value is absent, it returns -1.
ranges = np.array([[0,100],[100,200],[200,300]])
values = [23, 100, 188, 223, 999]
for v in values:
idx = getIndex(ranges,v)
print('{} in ({},{})'.format(v,ranges[idx,0],ranges[idx,1]) if idx!=-1 else '{} not found'.format(v))
23 in (0,100)
100 in (100,200)
188 in (100,200)
223 in (200,300)
999 not found