在查找表中查找范围内的值

7 投票
4 回答
12291 浏览
提问于 2025-04-15 23:05

我遇到了一个很简单的问题,但到现在为止我还没能想出在Python中解决它的方法。

我做了一个表格,长得像这样:

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

我想测试一个特定的数值,看看它是否在这些范围内,比如说,389 -> ASIA, 1300 -> LATAM, 5400 -> US。如果这个数值大于5409,就不应该返回任何结果。

通常情况下,我会用一个字典来做一对一的匹配。

但在这个情况下,我需要考虑这些范围,我现在不知道该怎么解决这个问题。

也许不需要给出完整的解决方案,你能给我一些建议,让我朝正确的方向去想吗?

这和电子表格里的vlookup功能很相似。

我觉得我的Python知识大概在基础和中级之间。

4 个回答

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

首先,先创建一个有序的索引:

index = sorted(table.iteritems())

然后,使用 bisect 来查找你的关键字:

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

你可以使用 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')

撰写回答