内部区间总是在全局区间内。所有区间都是整数,左闭,右开区间。
让我们举个例子。"global"间隔为[0,22]。"Inner"间隔为[3,6]和[12,15]。
对于这个例子,我期望:[0 3 [U[3、6[[6、12 [U[12、15[[15日22 [
我试图定义一个函数,但在迭代间隔时,索引搞砸了。
def allspans(r, spans):
pass
allspans((0, 22), [(3,6), (12,15)]) # expected : [(0, 3), (3, 6), (6, 12), (12, 15), (15, 22)]
是的,你必须迭代你的spans
,但要注意保持一个位置,以正确地填充空格。
from typing import Generator
def allspans(r, spans) -> Generator:
pos = 0
for lower, upper in spans:
if pos < lower:
yield pos, lower
yield lower, upper
pos = upper
if pos <= r[1]:
yield pos, r[1]
我发现使用Generator
更容易。用list()
转换成List
。
list(allspans((0, 22), [(3,6), (12,15)])) # [(0, 3), (3, 6), (6, 12), (12, 15), (15, 22)]
使用常规循环:
def allspans(r, spans):
intervals = []
intervals.append((r[0], spans[0][0]))
for i in range(len(spans)):
current_span = spans[i]
if i != 0:
intervals.append((spans[i - 1][1], current_span[0]))
intervals.append((current_span[0], current_span[1]))
intervals.append((spans[-1][1], r[1]))
return intervals
print(allspans((0, 22), [(3, 6), (12, 15)]))
# [(0, 3), (3, 6), (6, 12), (12, 15), (15, 22)]
使用itertools.chain
和itertools.pairwise
(Python 3.10+):
from itertools import chain, pairwise
def all_spans(r, spans):
start, end = r
it = chain((start,), chain.from_iterable(spans), (end,))
return [t for t in pairwise(it) if t[0] != t[1]]
首先,在所有区间端点上按顺序构造一个迭代器it
;则子范围为所有连续端点对,不包括两个连续端点相等的空子范围。