如何从Python中的另一个范围中排除范围?

时间:2017-06-06 13:24:11

标签: python algorithm range

假设我有一个范围(部分)和要排除的其他范围列表,由元组(开头,结尾)表示:

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')])

间隔被认为是显而易见的,但这是一个小问题。

3 个答案:

答案 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)]