Encontrar valor dentro de un rango en la tabla de búsqueda

Tengo el problema más sencillo de implementar, pero hasta ahora no he podido entender una solución en Python.

He construido una tabla que se parece a esta:

501 - ASIA 1262 - EUROPE 3389 - LATAM 5409 - US 

Probaré un cierto valor para ver si cae dentro de estos rangos, 389 -> ASIA, 1300 -> LATAM, 5400 -> US . Un valor mayor que 5409 no debe devolver un valor de búsqueda.

Normalmente tengo una coincidencia de uno a uno e implementaría un diccionario para la búsqueda.

Pero en este caso tengo que considerar estos rangos, y no estoy viendo cómo salir del problema.

Quizás sin proporcionar la solución completa, ¿podría proporcionar algunos comentarios que me ayuden a mirar en la dirección correcta?

Es muy similar a un vlookup en una hoja de cálculo.

Describiría mi conocimiento de Python como algo intermedio o intermedio.

Podrías usar el módulo bisect. En lugar de una búsqueda lineal, eso usaría una búsqueda binaria, que se espera sea más rápida:

 import bisect places = [ (501, 'ASIA'), (1262, 'EUROPE'), (3389, 'LATAM'), (5409, 'US'), ] places.sort() # list must be sorted for to_find in (389, 1300, 5400): pos = bisect.bisect_right(places, (to_find,)) print '%s -> %s' % (to_find, places[pos]) 

Se imprimirá:

 389 -> (501, 'ASIA') 1300 -> (3389, 'LATAM') 5400 -> (5409, 'US') 

Primero haz un índice ordenado:

 index = sorted(table.iteritems()) 

Luego, usa bisect para encontrar tu llave:

 _, value = bisect.bisect_left(index, (key, '')) 
 places = [(501,"ASIA"),(1262,"EUROPE"),(3389,"LATAM"),(5409,"US")] places.sort() def getSection(places,requests): PL= len(places) LAST=places[-1][0] for R in requests: for P in range(PL): if not (R < 0 or R>LAST):#keep away integers out of range if R<=places[P][0]: print R,"->",places[P][1] break else: break 

Una llamada a getSection,

 getSection(places,(5000000,389,1300,5400,-1,6000)) 

da:

 389 -> ASIA 1300 -> LATAM 5400 -> US 

Si solo tiene 5409 valores, pondría cada entero en el rango del diccionario y haría búsquedas normales. Cada entrada toma 12 bytes, el total es de solo 500 KB , así que, ¿para qué molestarse?

Aquí hay un código limpio para hacer esto:

 places = [ (501, 'ASIA'), (1262, 'EUROPE'), (3389, 'LATAM'), (5409, 'US'), ] def make_zones( borders ): last = 0 for n,v in borders: for i in range(last, n+1): yield i,v last = i+1 zones = dict(make_zones(places)) print zones[501], zones[502]