range()是惰性计算的轻量对象,仅存start、stop、step三个值,内存占用恒定;转为list则立即耗尽内存。

range() 不是列表,它不预分配内存
调用 range(10**9) 时,Python 并没有创建包含 10 亿个整数的列表,而只是生成一个 range 对象——它只存三个整数:start、stop、step。整个对象通常只占几十字节,和 range(10) 几乎一样大。
range 对象是惰性计算的,只在需要时算值
你不能直接通过索引访问任意位置(比如 r[999999999])就触发全部计算;它内部用数学公式 start + i * step 即时算出第 i 个值。遍历时每次调用迭代器的 __next__() 才算下一个数,不缓存历史结果。
- 支持
len(r):直接返回(stop - start) // step,不遍历 - 支持
in r:对大范围会做 O(1) 数学判断(比如检查n是否满足同余条件),不是逐个比对 - 不支持原地修改或追加:它天生不可变,没地方“爆内存”
但转成 list 就立刻崩
一旦执行 list(range(10**9)),Python 就真得在内存里塞 10 亿个 int 对象。在 64 位 CPython 中,单个 int 至少占 28 字节(含对象头),加上指针开销,轻松突破 20 GB 内存——绝大多数机器直接 MemoryError。
- 即使数值小(如全是 0),CPython 的
int对象也无法共享或压缩,每个都是独立对象 -
array.array('i', range(10**9))会好些(约 4 GB),但依然远超常规内存容量 - 真正需要大序列时,应考虑生成器、分块处理、或用
numpy.arange()(底层用连续 C 数组,但也要看内存)
注意 Python 2 的 xrange 是另一回事
Python 2 的 xrange 行为类似 Python 3 的 range,但它的 len() 在超大值时可能因 C long 溢出报错;而 Python 3 的 range 基于任意精度整数,len(range(10**100)) 都能算,只要不把它展开。
立即学习“Python免费学习笔记(深入)”;
真正容易被忽略的是:range 对象的「轻量」只在它保持为 range 时成立;任何试图把它当数据容器塞进内存的操作,都会暴露底层代价。










