假设我有一个范围(部分)和要排除的其他范围列表,由元组(开头,结尾)表示:
section=(1, 100) #Range from 1 to 100
toexclude=[(10,15),(40,50),(80,83)] #3 sub-ranges
我正在寻找一种有效的算法,它从这两个输入中返回一个新的范围列表,如:
[(1,9),(16,39),(51,79),(84,100)]
这是排除第二个范围列表的主要范围。
谢谢!
编辑:
实际上,deceze使用intervaltree的建议似乎很有趣。有几行:
from intervaltree import Interval, IntervalTree
t=IntervalTree()
t[1:100]="main"
t.chop(10,15)
t.chop(40,50)
t.chop(80,83)
t
IntervalTree([Interval(1, 10, 'main'), Interval(15, 40, 'main'), Interval(50, 80, 'main'), Interval(83, 100, 'main')])
间隔被认为是显而易见的,但这是一个小问题。
答案 0 :(得分:0)
有人想这样吗?
start, end = section
this_start = start
result = []
for exc_start, exc_end in toexclude:
this_end = exc_start - 1
result.append((this_start, this_end))
this_start = exc_end + 1
result.append((this_start, end))
编辑:根据Paco H.添加if
条款进行更正。评论
start, end = section
this_start = start
result = []
for exc_start, exc_end in toexclude:
if this_end == start:
start = exc_end + 1
else:
this_end = exc_start - 1
result.append((this_start, this_end))
this_start = exc_end + 1
if this_end <= end:
result.append((this_start, end))
答案 1 :(得分:0)
section=(1, 100) #Range from 1 to 100
toexclude=[(10,15),(40,50),(80,83)] #3 sub-ranges
rangelists = [x for excRange in toexclude for x in range(excRange[0], excRange[1] + 1)]
first, last = section[0], section[0]
out_ranges = []
for x in range(section[0],section[1] + 1):
if x not in rangelists:
if first == 'unset':
first = x
last = x
elif x in rangelists:
if last == x - 1:
out_ranges.append((first, last))
first = 'unset'
else:
continue
if first != 'unset':
out_ranges.append((first, last))
print out_ranges
答案 2 :(得分:0)
section=(1, 100) #Range from 1 to 100
toexclude=[(10,15),(40,50),(80,83)] #3 sub-rang
list1 = []
list2 = [section[0]]
[list1.append(x[0]-1) for x in toexclude]
[list2.append(x[1]+1) for x in toexclude]
list1.append(section[1])
print list(zip(list2, list1)
# [(1, 9), (16, 39), (51, 79), (84, 100)]