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