range是惰性生成的不可变序列对象,仅存start、stop、step参数,支持索引、切片、in等操作但无修改方法,内存高效且for循环中无需转list。

range 不是列表,而是一个不可变的序列类型对象。它不立即生成所有数字,而是按需计算,因此内存占用极小,适合大范围数值遍历。
range 对象的本质:惰性生成的序列
range 返回的是 range 类型的对象,不是 list。它实现了序列协议(支持 len()、索引、切片、in 操作等),但内部并不存储全部整数——只保存 start、stop、step 三个参数,访问某个位置时才实时算出对应值。
- 例如
range(10**6)几乎不占内存,而list(range(10**6))会创建百万个整数对象,明显更耗内存 - 支持正向/负向索引:
range(5)[2]得 2,range(5)[-1]得 4 - 支持切片:
range(10)[2:8:2]返回新的 range(2, 8, 2),不是列表
为什么不能直接用 list 的方法?
range 对象是只读、不可变的,没有 append()、extend()、remove() 等修改方法,也没有 sort() 或 reverse()。
- 错误示例:
r = range(5); r.append(5)→ AttributeError - 如需列表行为,必须显式转换:
list(range(5)) - 转换后才拥有列表全部能力,但也失去 range 的内存优势
常见误用与正确写法
不少初学者以为 for 循环中必须用 list(range(...)),其实完全没必要——for 语句直接迭代 range 对象即可,效率更高。
立即学习“Python免费学习笔记(深入)”;
- ✅ 推荐:
for i in range(100000): do_something(i) - ❌ 不必要:
for i in list(range(100000)): ...(多一次内存分配和拷贝) - 判断是否包含某数?
5 in range(10)是 O(1) 计算,不是逐个比对
与其他序列类型的兼容性
range 可参与多数序列操作,但要注意类型差异:
- 可与 tuple、str 一样用
+和*?不行——range 不支持拼接或重复(TypeError) - 可被 zip、enumerate 直接使用:
list(zip(range(3), 'abc'))→[(0, 'a'), (1, 'b'), (2, 'c')] - 传给函数时注意接收类型:某些函数(如 numpy.arange)接受 range,但 pandas.Series(range(5)) 会自动转为 int64 序列









