En primer lugar, no está del todo claro que la búsqueda binaria esté garantizada aquí . Es posible que la búsqueda lineal sea más rápida cuando el número de intervalos es pequeño.
Si está preocupado por el rendimiento, lo más prudente que hacer es perfilar el código, y tal vez ambos métodos de referencia en sus entradas típicas.
Renuncias un lado, la búsqueda binaria podría ser implementado por la clasificación de los intervalos de una vez, y luego repetidamente utilizando el módulo bisect
a hacer la búsqueda:
import bisect
intervals = [(999, 2333, 'int1'), (0, 128, 'int2'), (235, 865, 'int3')]
intervals.sort()
def find_int(intervals, val):
pos = bisect.bisect_left([interval[1] for interval in intervals], val)
if pos < len(intervals) and val >= intervals[pos][0]:
return intervals[pos]
else:
return None
print(find_int(intervals, 0))
print(find_int(intervals, 1))
print(find_int(intervals, 200))
print(find_int(intervals, 998))
print(find_int(intervals, 999))
print(find_int(intervals, 1000))
print(find_int(intervals, 2333))
print(find_int(intervals, 2334))
En lo anterior, supongo que los intervalos no se solapan , y que el intervalo incluye tanto sus puntos de inicio como de finalización.
Por último, para mejorar el rendimiento, se podría considerar la factorización [interval[1] for interval in intervals]
de la función y hacerlo sólo una vez al comienzo.
¿Vale la pena clasificarlo para usar la búsqueda binaria? [Si planea buscar solo unas pocas veces, no "vale la pena" ordenarlo, si planea buscar muchas veces, es] – amit
Los objetos tendrían que ser ordenados. – rplnt
¿Cuál es el límite superior e inferior absoluto de estos números? Puede ampliar los rangos en un "índice de mapa de bits" apropiado donde simplemente enumere todos los valores en el rango. –