让我们从存储在列表中的段[0,10]开始
[ [0, 10] ]
我收到了一组范围
[1,6]
[5, 8]
将分段划分为列表
[ [0,1], [1,5], [5,6], [6, 8], [8, 10] ]
在python中有什么好的数据结构/方法?
我不知道这类任务的术语,所以我的谷歌搜索毫无结果。
我总是可以用numpy.searchsorted
来蛮力,但这不会很干净
特别是每个子段实际上是具有许多属性的对象
而且,我有几轮
creating sub-segment object / receiving ranges for further partitioning
答案 0 :(得分:4)
我不确定您是如何查询数据结构或每个段具有的“属性”,但是根据您的示例,排序的数据结构就足够了。如果我们将您的列表展平,那么我们就会:
initial = [0, 10]
...
final = [0, 1, 5, 6, 8, 10]
我们可以通过以下方式将final转换为您的细分:
segments = [final[pos:pos+1] for pos in xrange(len(final) - 1)]
因此,对于每个额外的细分,我们将其与以下内容结合起来:
next_iter = sorted(set(prev_iter + segment))
对于大型列表而言,这会变得昂贵,但有些数据类型可以提供帮助。有序集合容器按排序顺序将其元素维护为集合。 sortedcontainers模块为此提供了SortedSet数据类型:
from sortedcontainers import SortedSet
segments = SortedSet([0, 10])
def add_segment(start, end):
segments.add(start)
segments.add(end)
add_segment(1, 6)
add_segment(5, 8)
print segments
# SortedSet([0, 1, 5, 6, 8, 10])
SortedSet支持快速索引和二等分,因此您可以这样查询:
print segments[2]
# 5
pos = segments.bisect(7)
print [segments[pos - 1], segments[pos]]
# [6, 8]
答案 1 :(得分:3)
在我看来,这似乎可以归结为排序问题。将初始范围插入数组,然后插入所有其他值。对数组进行排序,然后将其拆分成对,这将为您提供子范围。您也可以使用第一个验证范围设置最小值/最大值。