According to this great answer from @gnibbler, you can rewrite bisect
code yourself to fit your need
I modify the code from @gnibbler slightly, so that it can be used in your case
An optimization is that since your thresholds are also sorted, we don't need to search the whole list each time, but start from the last result index
def reverse_binary_search(a, x, lo=0, hi=None):
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)/2
if x > a[mid][4]:
hi = mid
else:
lo = mid+1
return lo
my_list = [[3,0.99,1], [2,0.98,54], [10,.85,4], [1,0.7,10], [12,0.69,31], [12,0.65,43], [1.56,0]]
threshold = [0.97, 0.90, 0.83, 0.6]
index_list = []
last_index = 0
for t in threshold:
last_index = reverse_binary_search(my_list, t, last_index) # next time start search from last_index
index_list.append(last_index)
Thanks @PhilCooper for valuable suggestions. Here is the code using generator as he proposed:
def reverse_binary_search(a, threshold):
lo = 0
for t in threshold:
if lo < 0:
raise ValueError('lo must be non-negative')
hi = len(a)
while lo < hi:
mid = (lo+hi)/2
if t > a[mid][6]:
hi = mid
else:
lo = mid+1
yield lo
my_list = [[3,0.99,1], [2,0.98,54], [10,.85,4], [1,0.7,10], [12,0.69,31], [12,0.65,43], [1.56,0]]
threshold = [0.97, 0.90, 0.83, 0.6]
index_list = list(reverse_binary_search(my_list, threshold))