Python,检查一个数字是否在列表中的多个范围内。
Python, check if a number is in a range of many ranges in a list.
如果有像这样的整数列表:
a_list = [2501, 2783, 3088, 3980, 465, 1001, 39392911, 39394382, 488955,489087, ......]
b_list = [474, 498, 47478821, 47479800, 3774, 8970, 484000, 486000......]
每2个数表示一个自然数的范围,例如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 万个数字需要以他的方式进行搜索。
如何编写代码以更快地完成它?
=============更多条件和信息=============
- 每个列表中的数字可能超过 10,000 个。
- 最多可搜索3000万个号码
- 列表的大小总是 n * 2
- a_list: [1st < 2, 3rd < 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
非常感谢。
把它们都扔进一本大字典里:
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 速度很快),然后查看它是否介于两个现有数字之间。
如果有像这样的整数列表:
a_list = [2501, 2783, 3088, 3980, 465, 1001, 39392911, 39394382, 488955,489087, ......]
b_list = [474, 498, 47478821, 47479800, 3774, 8970, 484000, 486000......]
每2个数表示一个自然数的范围,例如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 万个数字需要以他的方式进行搜索。
如何编写代码以更快地完成它?
=============更多条件和信息=============
- 每个列表中的数字可能超过 10,000 个。
- 最多可搜索3000万个号码
- 列表的大小总是 n * 2
- a_list: [1st < 2, 3rd < 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
非常感谢。
把它们都扔进一本大字典里:
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 速度很快),然后查看它是否介于两个现有数字之间。