2010-05-24 2 views
4

У меня есть простейшая проблема для реализации, но до сих пор мне не удалось найти решение в Python.Найти значение в пределах диапазона в таблице поиска

Я построил таблицу, которая выглядит примерно такой:

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

Я испытает определенное значение, чтобы увидеть, если он находится в пределах этих диапазонов, 389 -> ASIA, 1300 -> LATAM, 5400 -> US. Значение больше 5409 не должно возвращать значение поиска.

Как правило, я имею совпадение по одному, и будет реализовывать словарь для поиска.

Но в этом случае я должен учитывать эти диапазоны, и я не вижу своего выхода из проблемы.

Возможно, не предоставив полного решения, не могли бы вы предоставить некоторые комментарии, которые помогут мне взглянуть в правильном направлении?

Он очень похож на vlookup в таблице.

Я бы описал свое знание Питона как где-то между основным и промежуточным.

+1

ли число всегда отсортирован? – kennytm

ответ

13

Вы можете использовать модуль bisect. Вместо линейного поиска, который будет использовать бинарный поиск, который будет надеяться, будет быстрее:

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]) 

Напечатает:

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

+1 для 'bisect'. –

3

Сначала сделайте отсортированный индекс:

index = sorted(table.iteritems()) 

Затем, использование bisect, чтобы найти ваш ключ:

_, value = bisect.bisect_left(index, (key, '')) 
2

Если у вас всего 5409 значений, я бы просто поместил каждое целое число в словарь и выполнил обычный поиск. Каждая запись занимает 12 байт, всего всего 500Kb, так зачем беспокоиться.

Вот некоторые аккуратные код, чтобы сделать это:

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] 
2
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 

Вызов getSection,

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

дает:

389 -> ASIA 
1300 -> LATAM 
5400 -> US 
Смежные вопросы