为何range不是迭代器但reversed(range)是?为何可对反转range调用next?
为什么range不是迭代器,但reversed(range)是?为何反转后的range能调用next(),普通range不行?
嘿,这个问题问到点子上了!核心要先搞清楚**可迭代对象(Iterable)和迭代器(Iterator)**的区别,咱们一步步掰扯明白:
先明确两个关键概念
- 可迭代对象:只要实现了
__iter__()方法,能返回一个迭代器的对象就是可迭代的。你可以用for循环遍历它——因为for循环会自动调用它的__iter__()拿到迭代器,然后不断调用next()取元素。 - 迭代器:不仅实现了
__iter__()(返回自身),还必须实现__next__()方法,能逐个吐出元素,直到没元素时抛出StopIteration异常。
为什么range不是迭代器?
range对象是可迭代对象,但不是迭代器。它的__iter__()方法会返回一个全新的迭代器实例,而不是它自己。这意味着:
- 你可以多次用
for循环遍历同一个range对象(每次遍历都会生成新的迭代器); - 但你不能直接对
range调用next()——因为它根本没实现__next__()方法!
看示例:
r1 = range(6) next(r1) # 直接报错:TypeError: 'range' object is not an iterator
为什么reversed(range)是迭代器?
reversed()函数的作用就是接收一个可迭代对象,返回一个反向迭代器。这个返回的对象实打实实现了__next__()方法,所以你可以直接调用next()来逐个获取反向的元素:
r2 = reversed(range(6)) next(r2) # 返回5 next(r2) # 返回4 # 继续调用会依次返回3、2、1、0,再调用就抛出StopIteration
用代码验证类型
咱们用collections.abc里的类型判断工具来实锤:
from collections.abc import Iterable, Iterator r1 = range(6) print(isinstance(r1, Iterable)) # 输出True:range是可迭代的 print(isinstance(r1, Iterator)) # 输出False:range不是迭代器 r2 = reversed(range(6)) print(isinstance(r2, Iterator)) # 输出True:reversed返回的是迭代器
总结一下
range设计成可迭代对象而非迭代器,是为了支持多次遍历(每次遍历都生成新的迭代器);reversed()返回的是专门的反向迭代器,天生就带__next__()方法,所以能直接用next()调用。
内容的提问来源于stack exchange,提问作者MM1
相关产品推荐
相关产品推荐

