首页 > 解决方案 > 如何在范围列表中查找数字并返回索引

问题描述

对于此列表:

ranges = [[0,100],[100,200],[200,300]]

如何以python方式设计函数getIndex()来做到这一点:</p>

getIndex(ranges, 23)  --> 0    23 is in the 1st range
getIndex(ranges, 100) --> 1   100 is in the 2nd range
getIndex(ranges, 188) --> 1   188 is in the 2nd range
getIndex(ranges, 223) --> 2   223 is in the 3rd range
getIndex(ranges, 999) --> -1  Not found

这个问题可能已经回答了,但我找不到。

标签: pythonnumpyindexing

解决方案


这是一个没有任何循环的棘手方法。

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

我现在将这个水星定理开玩笑地称为:对于r由 定义的任何范围(r_start, r_end),如果任何数字n落在该范围内,那么(r_start-n)(r_end-n)将有相反的符号!当然,除非n等于r_start,否则会导致非负 0。(n=r_end超出范围)

从范围中减去 val 并在列轴上取乘积,基本上是在做(r_start-n)*(r_end-n). 这应该是负数,除了边界情况,我们用 if 做 OR (+) r_starts == n。然后我们只需在结果布尔数组上调用 np.where 。如果该值不存在,则返回 -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

推荐阅读