如何高效查找两个嵌套列表中长度相同的子列表?
优化方案:用集合/字典预处理长度,避免嵌套循环
你的核心问题是嵌套循环带来的O(nm)时间复杂度,150150=22500次对比,再乘400次外层循环,总操作数近900万,效率自然低下。可以通过预处理长度集合/字典把复杂度降到O(n+m),大幅提升速度。
场景1:只需要确认是否存在长度相同的子列表,或找到任意一对
如果只需要找任意一组符合条件的子列表,或者确认存在性,最快的方式是先把a中所有子列表的长度存入集合(集合的查询是O(1)常数时间),再遍历b检查长度是否在集合中:
# 如果a在400次外层循环中不变,把这行移到外层循环外面,只执行一次! a_lengths = {len(sublist) for sublist in a} # 外层循环(400次) for _ in range(400): # 遍历b找匹配 for sublist_b in b: if len(sublist_b) in a_lengths: # 找到目标,这里可以添加你的处理逻辑,比如打印、返回 print(f"找到匹配:a中子列表长度{len(sublist_b)},b中子列表{sublist_b}") break # 找到第一个就停止,不需要继续遍历
场景2:需要找出所有长度相同的子列表配对
如果要找出所有符合条件的子列表对,用字典把a的长度映射到对应的子列表列表,再遍历b匹配:
from collections import defaultdict # 同样,a不变的话,这部分移到外层循环外只做一次 a_len_map = defaultdict(list) for sublist_a in a: a_len_map[len(sublist_a)].append(sublist_a) # 外层循环(400次) for _ in range(400): matches = [] for sublist_b in b: current_len = len(sublist_b) if current_len in a_len_map: # 把a中所有同长度的子列表和当前b的子列表配对 matches.extend( (sa, sublist_b) for sa in a_len_map[current_len] ) # 处理所有匹配结果 print(f"本次找到{len(matches)}组匹配")
额外优化:如果a和b都固定不变
如果400次外层循环中a和b都没有变化,可以直接预处理出两者的公共长度,之后每次外层循环直接基于公共长度找子列表,连遍历都省了:
# 只执行一次预处理 a_lengths = {len(s) for s in a} b_lengths = {len(s) for s in b} common_lengths = a_lengths & b_lengths # 求长度交集 # 提前找出a中对应公共长度的子列表 a_common_map = {l: [s for s in a if len(s)==l] for l in common_lengths} # 提前找出b中对应公共长度的子列表 b_common_map = {l: [s for s in b if len(s)==l] for l in common_lengths} # 外层循环(400次) for _ in range(400): # 直接从预存的映射中取所有配对 all_matches = [] for length in common_lengths: all_matches.extend( (sa, sb) for sa in a_common_map[length] for sb in b_common_map[length] ) # 处理结果 print(f"本次找到{len(all_matches)}组匹配")
这种方式把最耗时的预处理都放到外层循环之外,400次循环只需要处理结果组装,速度会快得离谱。
内容的提问来源于stack exchange,提问作者wallbloggerbeing
相关产品推荐
相关产品推荐

