识别列表中的所有重叠元组

Joh*_*ohn 5 python

我目前有一个元组列表(尽管我控制列表和元组的创建,因此可以根据需要更改它们的类型)。每个元组都有一个开始和结束整数以及一个带有该范围源 ID 的字符串。我想要做的是识别元组中的所有重叠范围。

目前我有

a = [(0, 98, '122:R'), 
     (100, 210, '124:R'),
     (180, 398, '125:R'),
     (200, 298, '123:R')]
highNum = 0
highNumItem = ''
for item in a:
    if item[0] < highNum:
        print(highNumItem + ' overlaps ' + item[2])
        if item[1] > highNum:
            highNum = item[1]
            highNumItem = item[2]

    
# 124:R overlaps 125:R
# 125:R overlaps 123:R
Run Code Online (Sandbox Code Playgroud)

输出足够的重叠信息应该能够手动查看和修复。但是,它错过了识别某些重叠集。我不禁想到有一个相对明显的解决方案,我只是缺少或没有使用正确的搜索词来查找示例。但理想情况下,我希望输出实际上是

124:R overlaps 125:R & 123:R
125:R overlaps 123:R
Run Code Online (Sandbox Code Playgroud)

但是使用我的比较方法,我无法找到一种方法来捕捉重叠跨越超过 2 个相邻范围的罕见实例。如果有人能指出适合于此的函数或比较方法,我将不胜感激。

另外,如果重要的话,我目前坚持使用 python 2.7,但需要能够在 3rd 方应用程序允许的情况下将解决方案移植到 3.x。

Ed *_*ard 2

这应该有效:

import operator

def get_overlaps(end, remaining):
    output = []
    for r in remaining:
        if r[0] < end:
            # starts before the end
            output.append(r[2])
            continue
        break
    return output

def get_all_overlaps(lst):
    # thanks @Elan-R for this simplification
    for i, (start, end, name) in enumerate(lst):        
        overlaps = get_overlaps(end, lst[i+1:])
        if overlaps:
            print(name, "overlaps", " & ".join(overlaps))


a = [(0, 98, '122:R'), (100, 210, '124:R'), (180, 398, '125:R'), (200, 298, '123:R')]

# sort by start time
a.sort(key=operator.itemgetter(0)) # thanks to @moonGoose
get_all_overlaps(a)
Run Code Online (Sandbox Code Playgroud)

输出:

124:R overlaps 125:R & 123:R
125:R overlaps 123:R
Run Code Online (Sandbox Code Playgroud)

此代码迭代列表中的每个项目,然后检查每个后续项目以查看开始时间是否小于当前项目的结束时间。如果是,则会将该名称添加到重叠列表中。如果不是,它会随着开始时间的增加而停止检查当前项目,因此不会再有重叠。

(针对 Python 3.6 进行了测试,但应该适用于任何版本)