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

如何用更简洁的算法从列表筛选间隔大于指定值的元素

问题:实现间隔阈值过滤列表元素的简洁算法

给定列表

a = [44, 52, 59, 62, 174, 175, 178, 288, 292, 404, 408, 518, 521, 633, 637, 747, 751, 863, 867, 977, 980, 987]

需求说明

当指定间隔阈值为100时,最终过滤结果应为:

b = [62, 174, 288, 404, 518, 633, 747, 863, 977]

核心规则:

  1. 首先找到第一个满足下一个元素与当前元素差值大于阈值的元素,将其加入结果;
  2. 之后遍历列表,只要当前元素与结果中最后一个元素的差值大于阈值,就将当前元素加入结果。

现有实现代码

def pick(lst, gap):
    result = []
    first_item_picked = False
    for idx, x in enumerate(lst):
        try:
            if not first_item_picked and idx < len(lst)-1 and lst[idx+1]-x > gap:
                first_item_picked = True
                result.append(x)
            elif x - lst[idx-1] > gap:
                result.append(x)
        except:
            print(idx,x)
    return result

b = pick(a,100)
print(b)

简洁实现方案

方案1:利用itertools.pairwise简化相邻元素对比(Python 3.10+)

通过pairwise直接获取相邻元素对,快速定位第一个符合条件的元素,再遍历后续元素筛选:

import itertools

def pick(lst, gap):
    result = []
    # 定位第一个需要保留的元素
    for i, (curr, next_val) in enumerate(itertools.pairwise(lst)):
        if next_val - curr > gap:
            result.append(curr)
            last = curr
            # 遍历后续元素,筛选与上一个保留元素差值超阈值的项
            for num in lst[i+1:]:
                if num - last > gap:
                    result.append(num)
                    last = num
            return result
    return result

# 测试
a = [44, 52, 59, 62, 174, 175, 178, 288, 292, 404, 408, 518, 521, 633, 637, 747, 751, 863, 867, 977, 980, 987]
print(pick(a, 100))  # 输出: [62, 174, 288, 404, 518, 633, 747, 863, 977]

方案2:纯遍历优化版(无依赖)

去掉冗余的try-except(边界可通过索引判断处理),逻辑更清晰:

def pick(lst, gap):
    result = []
    n = len(lst)
    # 找第一个符合条件的元素
    for i in range(n - 1):
        if lst[i+1] - lst[i] > gap:
            result.append(lst[i])
            last = lst[i]
            # 处理后续元素
            for num in lst[i+1:]:
                if num - last > gap:
                    result.append(num)
                    last = num
            return result
    return result  # 无符合条件元素时返回空列表

# 测试
a = [44, 52, 59, 62, 174, 175, 178, 288, 292, 404, 408, 518, 521, 633, 637, 747, 751, 863, 867, 977, 980, 987]
print(pick(a, 100))

方案3:生成器实现(代码更紧凑)

用生成器逐步产出结果,避免额外列表存储,适合处理大数据量:

def pick(lst, gap):
    it = iter(lst)
    try:
        prev = next(it)
    except StopIteration:
        return  # 空列表直接返回
    # 定位第一个保留元素
    for curr in it:
        if curr - prev > gap:
            yield prev
            last = curr
            yield last
            break
        prev = curr
    # 筛选剩余元素
    for curr in it:
        if curr - last > gap:
            yield curr
            last = curr

# 测试
a = [44, 52, 59, 62, 174, 175, 178, 288, 292, 404, 408, 518, 521, 633, 637, 747, 751, 863, 867, 977, 980, 987]
b = list(pick(a, 100))
print(b)  # 输出: [62, 174, 288, 404, 518, 633, 747, 863, 977]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:32:07