我有一系列ID范围的元组,例如,
[(0,2), (3,6), (7,10), (11,14), (15,21), etc.]
另外,我有多个ID整数列表,例如
[1, 2, 4, 11, 12, 15, 17, 20, 22, 24, ...], [2, 3, 5, 10, 13, 15, 18, 20, 23, 24, ...], etc.
列表的长度不一定相同。
我正在寻找一种更好的方法来返回在其范围内的每个列表中至少有一个整数的元组,例如列表1中的“1”和列表2中的“2”匹配元组列表[0]列表1中的(范围0-2)或“11”和列表2中的“13”匹配元组列表[3](范围11-14)。
我可以遍历元组和列表,但是对于大型列表来说这很麻烦而且速度很慢。有更有效和简洁的方式吗?
答案 0 :(得分:1)
使用bisect模块,我们可以通过查看元组的两个成员是否会在保持排序顺序的同时插入该列表中的不同索引来检查给定列表中是否存在元组范围中的数字。这假设列表已排序,但元组可以按任意顺序排列。
tups=[(2,0), (3,6), (7,10), (11,14), (15,21)]
lis=[[1, 2, 4, 11, 12, 15, 17, 20, 22, 24],
[2, 3, 5, 10, 13, 15, 18, 20, 23, 24]]
from bisect import bisect
print [(x,y) for x,y in tups if all((bisect(li,x) != bisect(li,y)) or (x in li or y in li) for li in lis)]
答案 1 :(得分:1)
tups = [(0,2), (3,6), (7,10), (11,14), (15,21), (600,612)]
int_list = [[1, 2, 4, 11, 12, 15, 17, 20, 22, 24], [2, 3, 5, 10, 13, 15, 18, 20, 23, 24]]
for a,b in tups:
f = set(range(a,b+1))
if all(f.intersection(x) for x in int_list):
print (a,b)
使用set intersection,您应该能够得到答案:
(0, 2)
(3, 6)
(11, 14)
(15, 21)
所有元组的范围在所有列表中由至少一个匹配的整数表示。
说明:每个元组都转换为包含范围。检查每个范围是否与发电机中的所有可能列表相交。如果任何元组与列表没有交集,则all()继续下一个元组。如果元组与所有列表相交,则all()返回true,并将元组(a,b)返回给用户。