Python 列表推导比 for+append 快多少?实测 100 到 10 万,结论和你想的不一样
「写列表别用 for+append,用列表推导更快」——这话对一半。我在 CPython 3.13.14 上跑了一组实测,结论有点反常识。
实测:三种写法同台比
对比三种:列表推导 [i*2 for i in range(n)]、预分配后索引赋值、裸 append 循环。单位微秒,取每组最快一轮:
| 规模 n | 列表推导 | 预分配循环 | 裸 append 循环 |
|---|---|---|---|
| 100 | 3.6µs | 3.5µs(0.96x) | 4.4µs(1.21x) |
| 1,000 | 53.4µs | 53.0µs(0.99x) | 63.7µs(1.19x) |
| 10,000 | 562µs | 595µs(1.06x) | 640µs(1.14x) |
| 100,000 | 6,723µs | 6,912µs(1.03x) | 7,055µs(1.05x) |
结论一:推导和「预分配循环」几乎一样快
很多人以为列表推导是某种魔法加速,其实它底层就是「在 C 层先算好长度、一次性分配、再填值」。如果你用 [0]*n 先把位置占好,再用 lst[i]=... 索引赋值,速度和推导几乎持平(有的规模还略快一点)。
结论二:真正慢一丁点的是「裸 append」
裸 append 循环比推导慢 5%~20%,而且规模越小差距越明显(n=100 时慢 21%,n=10 万时只慢 5%)。原因很简单:每次 append 都是一次方法调用,外加「容量够不够、不够就扩容」的检查;而推导和预分配把这件事一次性做完了。
结论三:别神话推导,也别怕 append
- 数据量小(几百以内):三种写法随便选,差距在微秒级,可读性优先。
- 数据量大(十万、百万):优先列表推导,或者预分配索引赋值;尽量少用裸
append循环。 - 真正差距大的不是这里——是它隔壁的事:用
+=在循环里拼字符串(前面一篇聊过,比join慢几十倍),那个才是该优化的重灾区。列表这一块,推导和 append 差距其实很小。
附:推导和生成器别搞混
如果只要遍历、不想要整个列表躺在内存里,把方括号换成圆括号 (i*2 for i in range(n)) 就是生成器表达式——它不分配整个列表,内存占用 O(1),迭代到哪算到哪。要「全在内存里就位」用列表推导,要「流式处理」用生成器。
一句话总结:列表推导 ≈ 预分配循环 > 裸 append(慢一点点)。把「推导秒杀 append」改成「两者差不多,append 别裸着跑百万次」更准确。

浙公网安备 33010602011771号