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

忽略最后元素时,检查子列表是否存在于列表的最优方法

更高效的列表匹配方案

需求说明

我有如下结构的列表:

[
    [1, 2, 'A'],
    [3, 4, 'B'],
    [5, 6, 'C'],
    ...
]

需要检查该列表中是否存在某个子列表,其前两个元素为指定数字m和n,忽略最后一个字符串元素。

我已经实现了最直接的版本:

def contains_first_two(m : int, n : int, search : list) -> bool:
    
    for el in search:
        if el[0] == m and el[1] == n:
            return True
    
    return False

现在想知道有没有更高效的解决方案。

优化方案

1. 预处理为集合(适合多次查询)

如果需要多次执行查询操作,提前把所有子列表的前两个元素转换成元组存入集合,后续查询只需要O(1)时间复杂度:

# 预处理一次
preprocessed = {(el[0], el[1]) for el in search_list}

# 查询时直接判断
def contains_first_two(m: int, n: int) -> bool:
    return (m, n) in preprocessed

这种方式的优势在于,预处理只做一次,之后每次查询都极快,适合频繁查询的场景。

2. 使用生成器表达式简化代码(单次查询效率接近原实现)

如果只是单次查询,可以用生成器表达式替代显式循环,代码更简洁,效率和原实现几乎一致(底层都是迭代遍历):

def contains_first_two(m: int, n: int, search: list) -> bool:
    return any(el[0] == m and el[1] == n for el in search)

any()函数会在找到第一个匹配项时立即返回,和原实现的提前终止逻辑一致,但代码更紧凑。

3. 提前切片(可读性优化,无效率提升)

如果想让逻辑更清晰,可以提前取出子列表的前两个元素,但不会提升效率,只是代码可读性稍好:

def contains_first_two(m: int, n: int, search: list) -> bool:
    return any(el[:2] == [m, n] for el in search)

不过切片操作会创建新的列表,相比直接索引el[0]和el[1],反而会有微小的性能损耗,所以更适合追求代码可读性的场景。

方案选择建议

  • 频繁查询:选预处理集合的方案,把O(N)的查询成本降到O(1)
  • 单次/少量查询:用**生成器表达式+any()**的版本,代码简洁且效率和原实现相当
  • 优先可读性:可以用切片的写法,但要注意微小的性能损失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:35:12