拆分间隔长于阈值

Split intervals longer than a threshold

我有一个元组列表,每个元组定义一个间隔(开始、结束)。 我想拆分长于某个阈值的间隔。

示例:

Initial list: segs = [(0,100),(120,140),(160,200)] 
Threshold: 30

期望的输出:

split_segs = [(0,30),(30,60),(60,90),(90,100),(120,140),(160,190),(190,200)]

我想出了这个代码。

thr = 30.
split_segs = []
for a,b in segs:
    if b-a < thr:
        split_segs.extend([(a,b)])
    else:
        n = int((b-a)/thr)
        for i in range(n):
            if b-(a + (i+1)*thr) < thr:
                split_segs.extend([(a+(i+1)*thr, b)])
            else:
                split_segs.extend([(a+i*thr, a+(i+1)*thr)])

它可以工作,但对我来说看起来很笨拙。有更好或更 pythonic 的解决方案吗?

您可以通过扩展具有 threshold:

range 来更优雅地完成此操作
segs = [(0,100),(120,140),(160,200)]
threshold = 30
split_segs = []

for seg in segs:
    (a, b) = seg
    diff = b - a
    if diff <= threshold:
        split_segs.append(seg)
    else:
        split_segs.extend((n - threshold, n) for n in range(a + threshold, b + 1, threshold))
        if diff % threshold:
            # complete the gap
            split_segs.append((b - diff % threshold, b))

print(split_segs)

这是针对您的问题的递归解决方案:

segs = [(0,100),(120,140),(160,200)] 
threshold = 30

def divide(to_divide):
    divided = []
    if to_divide[1] - to_divide[0] > threshold:
        divided.append((to_divide[0], to_divide[0] + threshold))
        divided.extend(divide((to_divide[0] + threshold, to_divide[1])))
        return divided
    else:
        return [to_divide]

divided = [el for x in segs for el in divide(x)]
print(divided)

输出将是:

[(0, 30), (30, 60), (60, 90), (90, 100), (120, 140), (160, 190), (190, 200)]

更新:如果您更喜欢非递归解决方案,这是一个可能的解决方案:

segs = [(0,100),(120,140),(160,200)] 
threshold = 30

def divide(to_divide):
    divided = []
    divided.extend((to_divide[0] + i * threshold, to_divide[0] + (i+1) * threshold) for i in range((to_divide[1] - to_divide[0]) // threshold))
    if divided:
        if divided[-1][1] != to_divide[1]:
            divided.append((divided[-1][1], to_divide[1]))
    else:
        divided.append((to_divide[0], to_divide[1]))
    
    return divided

divided = [el for x in segs for el in divide(x)]
print(divided)