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

Python 3.x:嵌套数组中指定元素的精准查找及命中场景区分

解决区间数组的匹配与关联检索问题

看起来你已经搞定了区间完全匹配的逻辑,接下来咱们就重点解决未命中场景的区间关联问题。先明确下需求对应的核心逻辑:
我们要处理的是有序无重叠的区间数组(从你的示例能看出来firstArray的区间按起始值递增排列,且区间互不重叠),对于secondArray里的每个区间:

  1. 若和firstArray里的某个区间完全一致,直接输出该区间;
  2. 若没有完全匹配,找出所有和当前区间有重叠的firstArray区间——这就对应你说的"前后元素或包含它的元素"。

第一步:优化完全匹配的逻辑

你原来的嵌套循环效率有点低,咱们可以把firstArray转成元组集合(因为列表不能直接存进集合),这样判断完全匹配的时间复杂度能降到O(1):

firstArray = [[1,10],[11,31],[32,40],[41,61],[62,78]]
secondArray = [[1,10],[12,32],[33,39],[41,78]]

# 把firstArray的区间转成元组存进集合,方便快速匹配
first_interval_set = set(tuple(interval) for interval in firstArray)

第二步:处理未匹配的区间关联

因为firstArray是有序且无重叠的,我们可以利用这个特性高效定位关联区间:

  • 对于目标区间s = [s_start, s_end],所有和它重叠的区间,必然满足「起始值≤s_end且结束值≥s_start」;
  • 用二分查找可以快速缩小需要检查的区间范围,不用遍历整个数组。

下面是完整的实现代码:

import bisect

firstArray = [[1,10],[11,31],[32,40],[41,61],[62,78]]
secondArray = [[1,10],[12,32],[33,39],[41,78]]

first_interval_set = set(tuple(interval) for interval in firstArray)
# 提取firstArray所有区间的起始值,用于二分查找
first_starts = [interval[0] for interval in firstArray]

result = []

for s in secondArray:
    s_tuple = tuple(s)
    # 先检查完全匹配的情况
    if s_tuple in first_interval_set:
        result.append(s)
        continue
    
    s_start, s_end = s
    # 用二分查找定位可能关联的区间范围
    # 找到第一个起始值大于s_start的索引,前一个索引就是可能包含s_start的区间
    start_idx = bisect.bisect_right(first_starts, s_start) - 1
    # 找到第一个起始值大于s_end的索引,前一个索引就是可能包含s_end的区间
    end_idx = bisect.bisect_right(first_starts, s_end) - 1
    
    related_intervals = []
    # 遍历从start_idx到end_idx的区间,验证是否真的重叠
    for idx in range(start_idx, end_idx + 1):
        if 0 <= idx < len(firstArray):
            f_start, f_end = firstArray[idx]
            # 确认区间重叠:f的起始≤s的结束,且f的结束≥s的起始
            if f_start <= s_end and f_end >= s_start:
                related_intervals.append(firstArray[idx])
    
    result.append(related_intervals)

# 打印结果验证
for item in result:
    print(item)

运行结果验证

对应你的示例,输出结果如下:

[1, 10]
[[11, 31], [32, 40]]
[[32, 40]]
[[41, 61], [62, 78]]

完全符合你预期的需求:

  • [1,10]完全匹配,直接输出;
  • [12,32]关联到前后两个区间;
  • [33,39]被[32,40]包含,输出该区间;
  • [41,78]跨越两个区间,输出这两个区间。

为什么这个方案可行?

  1. 高效的完全匹配:用集合代替嵌套循环,时间复杂度从O(n*m)降到O(n + m);
  2. 精准的区间关联:利用有序数组的特性,通过二分查找快速缩小检查范围,避免无效遍历;
  3. 逻辑清晰:先处理完全匹配,再处理关联场景,代码可读性强,也容易扩展。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:28:14