我有最简单的问题需要实现,但到目前为止,我还没有能够解决Python中的解决方案。
我已经构建了一个类似于这个的表:
501 - ASIA
1262 - EUROPE
3389 - LATAM
5409 - US
我会测试某个值,看它是否属于这些范围389 -> ASIA, 1300 -> LATAM, 5400 -> US
。大于5409的值不应返回查找值。
我通常有一对一的匹配,并会为查找实现字典。
但在这种情况下,我必须考虑这些范围,而我并没有找到解决问题的方法。
也许没有提供整个解决方案,您能否提供一些有助于我朝着正确方向前进的评论?
它与电子表格中的vlookup
非常相似。
我会将我的Python知识描述为从基础到中间的某个地方。
答案 0 :(得分:14)
您可以使用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 :(得分:3)
首先制作一个排序索引:
index = sorted(table.iteritems())
然后,使用bisect找到你的密钥:
_, value = bisect.bisect_left(index, (key, ''))
答案 2 :(得分: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]
答案 3 :(得分: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