You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python优雅提取范围列表中的未覆盖区间?

优雅提取未覆盖区间的Python实现

嘿,这个问题我之前处理批量数据的时候也遇到过!Python确实能给出相当优雅的解决方案,尤其是结合排序和itertools的工具,完全能高效搞定数千级别的区间数据。

核心思路

不管区间数量多少,核心逻辑都是这两步:

  1. 合并重叠/相邻的覆盖区间:如果输入的覆盖区间有重叠(比如[(10,30), (20,50)]),先合并成连续的区间,避免重复计算空隙。
  2. 遍历合并后的区间,找出空隙:从完整范围的起点开始,逐个对比当前未覆盖的起点和每个覆盖区间的起点,把中间的空隙记录下来,最后再检查覆盖区间终点到完整范围终点的空隙。

具体实现

第一步:合并重叠区间

先写一个简单的合并函数,确保覆盖区间是连续且不重叠的:

def merge_intervals(intervals):
    if not intervals:
        return []
    # 按区间起始点排序
    sorted_intervals = sorted(intervals)
    merged = [sorted_intervals[0]]
    for current_start, current_end in sorted_intervals[1:]:
        last_start, last_end = merged[-1]
        # 如果当前区间和上一个合并区间重叠,就合并成更大的区间
        if current_start <= last_end:
            merged[-1] = (last_start, max(last_end, current_end))
        else:
            merged.append((current_start, current_end))
    return merged

第二步:用itertools提取未覆盖区间

Python 3.10+提供了itertools.pairwise,可以非常简洁地遍历相邻的区间对,我们用它来处理空隙:

from itertools import pairwise

def get_uncovered_ranges(full_start, full_end, covered_intervals):
    # 先合并覆盖区间
    merged_covered = merge_intervals(covered_intervals)
    # 在合并后的区间前后添加虚拟边界,方便统一处理开头和结尾的空隙
    extended_intervals = [(full_start - 1, full_start - 1)] + merged_covered + [(full_end + 1, full_end + 1)]
    uncovered = []
    # 遍历每一对相邻的区间
    for (_, prev_end), (curr_start, _) in pairwise(extended_intervals):
        gap_start = prev_end + 1
        gap_end = curr_start - 1
        # 如果空隙有效(起点<=终点),就加入结果
        if gap_start <= gap_end:
            uncovered.append((gap_start, gap_end))
    return uncovered

测试你的例子

把你给出的参数代入函数:

full_start, full_end = 1, 100
covered = [(10, 50), (90, 100)]
print(get_uncovered_ranges(full_start, full_end, covered))

输出结果正好是:[(1, 9), (51, 89)],完美符合预期!

为什么这个方法好用?

  • 高效性:排序的时间复杂度是O(n log n),后续遍历都是线性的,哪怕数千个区间也能快速处理。
  • 鲁棒性:自动处理覆盖区间乱序、重叠的情况,不用额外做判断。
  • 可读性:用pairwise把区间对比逻辑简化,代码更直观,后续维护也方便。

内容的提问来源于stack exchange,提问作者CodeNoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:47:51