Python,检查一个数字是否在列表中的多个范围的范围内。

时间:2015-02-16 20:27:35

标签: python list search

如果有这样的整数列表:

a_list = [2501, 2783, 3088, 3980, 465, 1001, 39392911, 39394382, 488955,489087, ......]
b_list = [474, 498, 47478821, 47479800, 3774, 8970, 484000, 486000......]

每两个数字表示一系列自然数,例如 a_list 的范围是:

2501     2783      # 2501,2502,2503,2504,2505,2506,......,2783
3088     3980 
465      1001 
39392911 39394382 
488955   489087
......

对于给定的数字,搜索它所属的范围,优先级为a_list> b_list,即如果在a_list中找到范围,则停止搜索并继续搜索下一个数字。

我试用了约50个数字,大约需要7分钟。我有一个大数据集,可能需要以他的方式搜索2000万个数字。

如何对此进行编码以更快地完成?

=============更多条件和信息=============

  • 每个列表中的数字可能超过1万个。
  • 可能有多达3000万个搜索号码。
  • 列表的大小始终为n * 2
  • a_list:[1st<第2,第3< 4,......]
  • 列表中的数字可能会多次出现。
  • 优先级:a_list> b_list。

我的代码如下:

hasFound = 0

if hasFound == 0:
    for x, y in izip(*[iter(a_list)]*2):   # gives every 2 numbers
        if aNumber in range(x,y):
            a_list_counter +=1 
            hasFound = 1
            break

if hasFound == 0:       
    for x, y in izip(*[iter(b_list)]*2):
        if aNumber in range(x,y):
            b_list_counter += 1
            hasFound = 1
            break

非常感谢提前。

1 个答案:

答案 0 :(得分:1)

将它们全部放在一本大词典中:

a_list = [2501, 2783, 3088, 3980, 465, 1001, 39392911, 39394382, 488955,489087, ......]
b_list = [474, 498, 47478821, 47479800, 3774, 8970, 484000, 486000......]
# into
ranges = {'a': [2501, 2783, 3088, 3980, 465, 1001, 39392911, 39394382, 488955,489087, ......],
          'b': [474, 498, 47478821, 47479800, 3774, 8970, 484000, 486000......]}

然后按顺序浏览每个列表,主要是以前的方式:

numbers = [list of your target numbers]
scores = {} # dict to store results in

for number in numbers:

    for range_name in sorted(ranges):
        range_list = ranges[range_name]
        groups = zip(*[iter(range_list)] * 2)
        if any(start <= number < end for start,end in groups):
            scores.setdefault(range_name, 0) += 1

或者(我不确定这是否更快)你可以这样做:

for number in numbers:
    for range_name in sorted(ranges):
        range = ranges[range_name]
        if sorted(range + [number]).index(number) % 2:
            scores.setdefault(range, 0) += 1

在这种情况下,您将新数字投入到排序列表中,重新排序(使用TimSort快速排序),并查看它是否介于两个现有数字之间。