拆分间隔长于阈值
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)
我有一个元组列表,每个元组定义一个间隔(开始、结束)。 我想拆分长于某个阈值的间隔。
示例:
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)