python 3 的 range 对象内存恒定约48字节,支持 o(1) 成员判断和切片操作,而 python 2 的 xrange 不支持切片、成员判断为 o(n) 且缺乏溢出防护。

Python 3 的 range 对象本身不存数字,只存 start、stop、step 三个整数和少量元信息,所以无论范围多大,内存占用都恒定在约 48 字节——它比 Python 2 的 xrange 更省内存,不是因为它“更惰性”,而是因为它的设计更数学化、更抽象。
range(10**15) 和 xrange(10**15) 内存占用真的一样?
不一样。range 在 Python 3 中是不可变序列类型,对象大小与数值大小完全无关;而 Python 2 的 xrange 虽然也不展开数据,但内部实现更轻量、也更原始:它没有为大整数做溢出防护,某些极端值(如 xrange(2**63))可能静默截断或崩溃。实测 sys.getsizeof(range(10**15)) 和 sys.getsizeof(range(10)) 几乎相等;xrange 同样省,但没做边界校验,可靠性低。
为什么 999 in range(1000) 是 O(1),而 xrange 不是?
Python 3 的 range 把成员判断转成纯算术:检查 (n - start) % step == 0 且 n 落在有效区间内,全程不生成任何中间值;Python 2 的 xrange 没实现 __contains__,表达式 999 in xrange(1000) 实际触发线性扫描,最坏要迭代 1000 次。
- 这不只是“省内存”,更是算法层面的升级:前者是数学判断,后者是遍历模拟
-
10**12 in range(10**12 + 1)瞬间返回True;换成xrange会卡死甚至失败 - 如果你依赖
in判断(比如做坐标过滤、ID 区间校验),这点差异直接影响响应时间
切片操作返回新 range,不是列表也不是拷贝
Python 3 的 range[::] 用原参数推导新参数,构造另一个恒定内存的 range 对象;Python 2 的 xrange 根本不支持切片——写 xrange(10)[2:5] 直接抛 TypeError。
-
r = range(0, 100, 2); s = r[5:15:2]→s是range(10, 30, 4),仍只占 ~48 字节 - 这种切片能力让
range可用于分块调度、步长重映射等场景,而xrange只能靠手动计算起止值 - 注意:
range(5)[::-1]在 Python 3 返回range(4, -1, -1),不是列表,别误以为是反转后的 list
真正容易被忽略的点是:range 的内存优势只作用于 range 对象本身;一旦你调用 list(range(n)),就立刻退化成 Python 2 的 range() 行为——O(n) 内存爆炸。这不是 range 的问题,是你主动放弃了它的数学抽象能力。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











