Python列表过滤效率优化:寻求高效筛选符合双条件的对应元素方案
需求与性能优化请求
免责声明
本人并非专业程序员,若表述不够精准,提前致歉。
需求说明
我有两个列表counter和slope,需要筛选出slope中满足以下两个条件的元素:
- 数值小于等于-1
- 该元素在
slope中无前序重复项
随后返回counter中与这些符合条件的slope元素对应的元素,组成新列表filter_count。
当前低效实现代码
filter_count = [i for i,j in zip(counter, slope) if i-1 == slope.index( slope[int(i-1)] ) and j<=-1]
性能问题
整段脚本执行耗时约13秒,上述代码的耗时占比高达99.9%,急需更高效的实现方案。
附参考示例图(实际场景中列表规模远大于示例):示例效果参考图
高效实现方案
你的代码效率极低的核心原因是slope.index()方法——它每次都会从头遍历列表查找元素,时间复杂度为O(n),当列表规模较大时,多次调用会让整体时间复杂度飙升至O(n²)。
推荐使用集合记录已出现元素的方式,只需一次遍历即可完成筛选,时间复杂度降至O(n),实现代码如下:
filter_count = [] seen = set() for cnt, slp in zip(counter, slope): if slp <= -1 and slp not in seen: filter_count.append(cnt) seen.add(slp)
代码说明
seen集合用于存储已经处理过的符合条件的slope元素,集合的成员判断操作(in)时间复杂度为O(1),远快于列表的index()方法- 遍历
counter和slope的对应元素,每遇到满足条件(数值≤-1且未在seen中出现过)的slope元素,就将对应的counter元素加入结果列表,同时把该slope元素加入seen集合,避免后续重复处理
如果偏好列表推导式写法,也可以结合生成器实现(可读性略逊于循环版本):
seen = set() filter_count = [ cnt for cnt, slp in zip(counter, slope) if slp <= -1 and not (slp in seen or seen.add(slp)) ]
这里利用了seen.add(slp)返回None的特性,逻辑与循环版本完全一致。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

