这两个技巧是代码级优化的“第一原则”,改动成本极低,收益却非常直接。它们的共同思路是:让 Python 能做的事,尽量别自己用循环手写。
优先使用内置函数与标准库
Python 的内置函数(如 sum、max、sorted)和标准库模块(如 collections、itertools)底层大多用 C 语言实现,执行速度远快于你用纯 Python 写的等价逻辑。同时,它们经过了无数场景的验证,比自己手写的代码更可靠、更少 bug。
- 能用内置函数就绝不手写循环
- 累加数字 →
sum(nums),而不是total = 0; for n in nums: total += n - 判断列表中是否存在满足条件的元素 →
any(x > 0 for x in nums),而不是写 for 循环手动 break - 判断是否所有元素都满足条件 →
all(isinstance(x, int) for x in items) - 最大值/最小值 →
max(lst)/min(lst),而不是自己遍历比较
- 善用标准库提供的高效容器和工具
collections.deque在两端插入删除是 O(1),而list.pop(0)是 O(n)。做队列时一定优先用 dequecollections.defaultdict和Counter省去大量“检查 key 是否存在”的手动逻辑itertools里的chain、groupby、product等可以替代深层嵌套循环,代码更清晰且执行更高效
实用心法:动手写循环之前,先问自己三个问题——标准库有没有现成的模块?内置函数能不能直接搞定?itertools 或 collections 有没有更好的工具?大部分时候答案都是“有”。
减少循环层级
嵌套循环是性能杀手,时间复杂度很容易从 O(n) 变成 O(n²) 甚至更差。减少循环层级,本质上就是在降低算法的时间复杂度。
常见减层策略
- 用字典/集合的 O(1) 查找代替内层扫描
- 典型场景:判断一个元素是否在另一个集合中存在
- 错误做法:两层循环遍历两个列表 → O(n*m)
- 优化做法:先将待查找的列表转为
set,然后单层循环判断 → 降为 O(n+m)
# 优化前
common = []
for a in list_a:
for b in list_b:
if a == b:
common.append(a)
# 优化后
set_b = set(list_b)
common = [a for a in list_a if a in set_b]
- 用列表推导式/生成器表达式替代简单循环
- 列表推导式在 Python 内部用 C 循环执行,比显式的
for循环快。生成器表达式在不需要立刻生成完整列表时更省内存。 - 注意:推导式不要嵌套超过两层,否则可读性暴跌,这时候宁可牺牲一点性能保持清晰。
- 利用
itertools扁平化多层循环
itertools.product代替多重循环做笛卡尔积itertools.chain把多个可迭代对象串成一个,避免“外层循环套内层遍历”的写法
- 尽量用向量化操作替代 Python 层循环
- 数据处理时,优先用 NumPy/Pandas 的向量化运算,它们把循环推到了底层 C/Fortran 库,速度能提升 10~100 倍。
- 比如
np.sum(a b)代替sum(xy for x,y in zip(a,b)),不只是减少循环层级,而是直接把循环移出 Python。
关键原则:减少循环层级不是必须把代码变成“一行流”,而是在保持可读性的前提下,通过选用合适的数据结构和库函数,把嵌套的 O 复杂度降下来。这种优化往往比调整单个语句的细节收益大得多。