You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python列表推导式无法像[1]*i一样预分配内存?

列表推导式与[1]*i的内存分配差异解析

问题背景

执行以下代码时:

import sys

for i in range(30):
    print(sys.getsizeof([1 for _ in range(i)]))

输出结果为2的幂;而执行以下代码时:

for i in range(30):
    print(sys.getsizeof([1]*i))

输出结果为线性增长的较小值。

疑问:第一个示例中Python似乎在列表推导式循环中反复创建并扩容数组,而第二个示例能一次性分配正确尺寸的数组。为何前者无法识别range(i)会生成i个元素从而进行优化?

核心原因

  • [1]*i的专属优化:这种语法是Python针对「固定元素重复生成列表」场景做的特殊优化。解释器执行时明确知道要创建的列表长度是i,可以直接分配刚好容纳i个元素的内存空间(加上列表对象本身的固定开销),因此内存占用随元素数量线性增长,和实际元素数精准匹配。

  • 列表推导式的通用适配逻辑:列表推导式是通用的迭代生成工具,需要兼容所有类型的迭代器——不仅是range这种有明确长度的迭代器,还包括没有__len__方法、无法提前获知元素数量的自定义迭代器。为了覆盖所有场景,它采用动态扩容策略:初始分配小容量内存,当元素数量超过当前容量时,按2的幂次扩容(比如4→8→16…),这就导致输出的内存大小呈现2的幂次特征。

哪怕推导式里用的是range(i)这种长度明确的迭代器,Python解释器也不会为这一种特殊场景修改通用逻辑——毕竟要保证所有迭代场景下的一致性,额外做类型判断反而会增加解释器的复杂度,得不偿失。

内容的提问来源于stack exchange,提问作者lezebulon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:11:11