Python 如何";“工会”;重叠范围到非重叠范围?

Python 如何";“工会”;重叠范围到非重叠范围?,python,range,aggregate,union,overlap,Python,Range,Aggregate,Union,Overlap,问题: 有人能建议一种更好或更具python风格的方法,将重叠范围对减少为非重叠范围对吗 背景: 我有一个表示开始和结束对的元组列表。我试图基本上完成所有开始-结束对的并集。输入开始-结束对具有重叠值,输出应表示没有任何重叠的输入开始-结束对 下面的代码很接近,但错误,因为它输出了一个不在输入中的额外范围(我也意识到它不是很好,为什么它是错误的)。有谁能建议一个更好的方法,或者一些我忽略的内置功能吗 为这个基本问题道歉。 谢谢你的帮助 ##create example data pairA =[

问题: 有人能建议一种更好或更具python风格的方法,将重叠范围对减少为非重叠范围对吗

背景: 我有一个表示开始和结束对的元组列表。我试图基本上完成所有开始-结束对的并集。输入开始-结束对具有重叠值,输出应表示没有任何重叠的输入开始-结束对

下面的代码很接近,但错误,因为它输出了一个不在输入中的额外范围(我也意识到它不是很好,为什么它是错误的)。有谁能建议一个更好的方法,或者一些我忽略的内置功能吗

为这个基本问题道歉。 谢谢你的帮助

##create example data
pairA =[(0,5),(10,12)]
pairB =[(1,2),(11,15)]
pairC =[(1,4),(10,12),(15,17)]

#combine the lists to one list
#ultimately may have n number of lists and felt it would be easier to
merged = pairA + pairB +pairC
# produce union of list * unpacks the arguments of a list
listUnion= sorted(set().union(*merged))

#this is the piece of code I am looking at improving
#it creates new start end pairs based on the union
lastElement =listUnion[-1]
outList=[]

for item in listUnion:
    #create start end pair from value i and i+1
    if item != lastElement:
        outList.append((item,listUnion[listUnion.index(item)+1]))
    else:
        #last element of the list, becomes the last element of list pair
        #it can be ignored
        pass
print outList 
"""output: [(0, 1), (1, 2), (2,4), (4, 5), (5, 10), (10, 11), (11, 12), (12, 15), (15, 
17)]
correct output: would not have (5,10) as there is no overlap here in the input """

<>编辑:添加了这个问题的可视化表示< /p> 不确定你的环境限制,但是如果你没有任何限制,你可能会考虑这个: 特别是,

result_tree = tree.union(iterable)

请你澄清一下这个问题好吗。我看到
[(0,5)、(1,2)]
产生
[(0,1)、(1,2)、(2,5)]
[(0,5),(1,5)]
会产生什么,
[(0,1),(1,5),(5,5)]
,或者仅仅是
[(0,1)]
,或者其他什么。这可能不是很像Python,因为我对Python的经验非常有限,但它很有效

pairs_a = [(0, 5), (10, 12)]
pairs_b = [(1, 2), (11, 15)]
pairs_c = [(1, 4), (10, 12), (15, 17)]

merged = pairs_a + pairs_b + pairs_c
merged.sort()

set_list = []
cur_set = set()
cur_max = merged[0][1]
for pair in merged:
    p0, p1 = pair
    if cur_max < p0:
        set_list.append(cur_set)
        cur_set = set()
    cur_set.add(p0)
    cur_set.add(p1)
    if cur_max < p1:
        cur_max = p1
set_list.append(cur_set)

out_list = []
for my_set in set_list:
    my_list = sorted(my_set)
    p0 = my_list[0]
    for p1 in my_list[1:]:
        out_list.append((p0, p1))
        p0 = p1

# more pythonic but less readable in spite of indentation efforts:
# out_list = [pair
#             for zipped in [zip(list[:-1], list[1:])
#                            for list in [sorted(set)
#                                         for set in set_list]]
#                 for pair in zipped]

# alternate ending:
# out_list = [sorted(set) for set in set_list]

print(out_list)
pairs_a=[(0,5)、(10,12)]
配对b=[(1,2)、(11,15)]
配对c=[(1,4)、(10,12)、(15,17)]
合并=对a+对b+对c
merged.sort()
set_list=[]
cur_set=set()
cur_max=merged[0][1]
对于合并中的对:
p0,p1=对
如果cur_max

其思想是首先按第一项对所有范围对进行排序。这就是
merged.sort()
所做的(它使用连续的元组成员来消除歧义,但这在这里并不重要)。然后我们在排序的范围对上循环,只要我们在一组重叠的范围内,我们就将所有开始和结束添加到当前集合中。为了知道束何时结束,我们保持所有范围结束的最大值。一旦到达超出此最大值的范围开始,我们通过将当前集合附加到列表中来存储当前集合,然后开始新的集合。最后一组必须添加到循环后的列表中。现在我们有了一个集合列表,我们可以很容易地将其转换为列表列表或成对列表。

查找
Interval
类。这个抽象很可能将您从现在所做的工作中解放出来,并直接导致此解决方案和更多解决方案。
(0,5)
(1,2)
的超集。你为什么不干脆完全放弃
(1,2)
?它不应该是[(0,1),(1,2),(2,4),(4,5)…]?@JohnGordon“断点”是以后需要的。@accumulation你是对的,我更新了帖子对不起,没有清晰性,0,51,5会产生(0,1),(1,5)。我会调查intervaltreeThanks Walter。我将调整代码,看看我是否能得到它的权利。它会产生一个额外的重叠(17,10),但我欣赏另一种方法。代码输出(17,10),其中包含一些其他输出对。哦,在我的python 3.7.0中没有。你有什么python?我想我刚刚修复了它,将
列表(我的集合)
替换为
排序(我的集合)
。显然,(某些?)集合在转换为列表时是否显示为已排序,或者在迭代时是否显示为已排序,这取决于Python。谢谢,我应该指定,这必须在2.7中。我还没来得及做,你就把它弄坏了。如果我能想出一个蟒蛇式的方法。我会把它寄给你的。很好。我还添加了一个“备选结尾”,一个“列表列表”输出,您可能会发现这很有用。