python 3 的 range 对象内存恒定、in 查找 o(1)、切片返回新 range,均靠数学计算实现;python 2 的 range 内存随规模暴增,xrange 功能受限且不支持高效 in 和切片。

Python 3 的 range 对象本身几乎不占内存,和范围大小完全无关;Python 2 的 range 会立刻生成完整列表,xrange 虽省内存但功能受限——真正省在哪、怎么省、为什么容易误判,得看这三处。
range(10**15) 在 Python 3 中只占约 48 字节
它不存任何数字,只存 start、stop、step 三个整数和少量元信息。你可以用 sys.getsizeof(range(10**6)) 和 sys.getsizeof(range(10**15)) 实测,结果基本一致。而 Python 2 的 range(10**6) 会分配百万个 int 对象加列表头开销,轻松吃掉 80MB+ 内存。
常见错误现象:range(10**8) 在 Python 3 中能秒建、秒查 in、秒切片;有人却在 Python 3 里写 list(range(10**8)),直接触发 MemoryError——爆内存的从来不是 range,而是你主动把它“展开”了。
999 in range(1000) 是 O(1) 数学判断,不是遍历
Python 3 的 range.__contains__ 直接解算:只要满足 (n - start) % step == 0 且数值落在区间内,就立刻返回 True。不需要生成、不触发迭代、不走循环。
对比 Python 2 的 xrange:999 in xrange(1000) 是线性扫描,最坏要比 1000 次;而 Python 2 的 range 更糟——先造出列表再用 in 查,双重浪费。
性能影响明显:10**12 in range(10**12 + 1) 在 Python 3 中仍是瞬时响应;在 Python 2 中写等效逻辑,要么卡死,要么根本不敢试。
切片 range[5:15:2] 返回新 range,不展开数据
比如 r = range(0, 100, 2)(偶数序列),s = r[5:15:2] 不拷贝、不计算中间值,而是用数学推导出新参数:range(10, 30, 4),结果对象仍只占几十字节。
Python 2 的 xrange 根本不支持切片——写 xrange(10)[2:5] 直接抛 TypeError;range 虽支持,但返回的是列表切片,已失去惰性优势。
容易踩的坑:range(5)[::-1] 在 Python 3 返回 range(4, -1, -1),仍是轻量对象;有人误以为它像列表一样“反转后变大”,其实没变——但若接着调 list(),就又掉进内存陷阱。
真正关键的分水岭不在“range 本身”,而在你是否无意中调用了 list()、tuple()、print()(触发 __repr__ 展开)、或用它参与需要完整序列的第三方库操作。这些动作才把恒定内存的抽象,瞬间变成 O(n) 的真实压力。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











