Python 循环优化的常见技巧

4次阅读

推荐用 enumerate 替代 range(len(…))遍历列表,因其更高效、可读;成员检查优先用 in 而非手写循环;过滤求和等场景用生成器表达式省内存;循环内不变表达式需提前提取。

Python 循环优化的常见技巧

enumerate 替代 range(len(...))

直接索引遍历列表时,range(len(my_list)) 看似直观,但会多一次 len() 调用、生成一个不必要的整数序列,且可读性差。pythonenumerate() 是专为此设计的内置函数,它返回 (index, item) 元组,底层用 C 实现,开销极小。

  • ✅ 推荐写法:for i, item in enumerate(my_list):
  • ❌ 避免写法:for i in range(len(my_list)): item = my_list[i]
  • 注意:如果只需要索引(不取值),仍用 range(len(...)) 更轻量;但这种情况本身往往暗示逻辑可重构

提前用 in 检查成员存在性,别写循环手动找

判断某个值是否在容器中,90% 场景下不该手写 for 循环加 break。Python 容器的 __contains__ 方法(即 in 操作)对 setdict 是 O(1),对 list 是 O(n),但底层用 C 实现,比纯 Python 循环快 3–5 倍。

  • ✅ 正确姿势:if x in my_set:(优先把查找目标转成 set
  • ❌ 过度优化:found = False; for v in my_list: if v == x: found = True; break
  • 特别注意:list 上反复 in 查找,应先转 set —— my_set = set(my_list) 的一次性开销远低于多次线性扫描

用生成器表达式替代 list 推导式做中间过滤

当循环只是为后续操作(如 sum()any()max())提供数据源,且不需要所有结果都驻留内存时,用生成器表达式(圆括号)能省下大量内存并可能提前终止。

  • ✅ 内存友好:sum(x * 2 for x in data if x > 0)
  • ❌ 浪费内存:sum([x * 2 for x in data if x > 0]) —— 先建完整列表再求和
  • 关键区别:生成器表达式不支持索引或重复遍历;若需多次使用,才考虑转成 list 或用 itertools.tee()
  • 性能提示:any()all() 天然配合生成器,遇到第一个 TrueFalse 就停,效率极高

避免在循环内重复计算不变表达式

把循环外就能确定的值、函数调用、属性访问提出来,尤其是涉及模块导入、对象方法绑定、正则编译等高成本操作。

立即学习Python免费学习笔记(深入)”;

  • ✅ 提前提取:pattern = re.compile(r'd+'); for line in lines: pattern.search(line)
  • ❌ 重复执行:for line in lines: re.compile(r'd+').search(line) —— 每次都重新编译正则
  • 常见陷阱:for item in items: item.some_method() 中,如果 some_method 是无参且返回相同结果,可提成 cached_result = item.some_method()
  • 注意:Python 不会自动优化循环内未变化的变量引用,哪怕看起来“显然不变”

真正卡顿的循环,往往不是算法复杂度问题,而是混进了隐式 I/O、重复对象创建、或没意识到某些操作本可在循环外固化。动手前先看三眼:这个计算真的必须在每次迭代里做吗?

text=ZqhQzanResources