这就意味着,可以将迭代器对象作为iter函数的参数,生成一个新的迭代器对象 。不是吗?
>>> numbers = [1, 2, 3]>>> iterator1 = iter(numbers)>>> iterator2 = iter(iterator1) # 迭代器对象作为参数
以上最终得到的iterator2是一个迭代器 。不过,要注意,iterator1和iterator2的关系:
>>> iterator1 is iterator2True
iter函数的参数如果是一个迭代器,返回对象仍然是该迭代器对象自身 。
结论:迭代器是可迭代对象,所有迭代器都是自己的迭代器 。
def is_iterator(iterable):return iter(iterable) is iterable
困惑了吗?
继续 。
迭代器没有长度,因此无法索引 。这个认识必须要建立起来 。
>>> numbers = [1, 2, 3, 5, 7]>>> iterator = iter(numbers)>>> len(iterator)TypeError: object of type 'list_iterator' has no len()>>> iterator[0]TypeError: 'list_iterator' object is not subscriptable
从Python程序员的角度来看,使用迭代器可以做的唯一有用的事情就是:将迭代器传给内置的next函数、或遍历迭代器:
>>> next(iterator)1>>> list(iterator)[2, 3, 5, 7]
如果我们第二次遍历迭代器,我们将一无所获:
>>> list(iterator)
这就是说,迭代器可以认为是一次性的惰性的可迭代对象,这意味着它们只能遍历一次 。

文章插图
正如上表中所示,可迭代对象并不总是迭代器,但迭代器总是可迭代对象:
所谓迭代器协议,即:
- 可以作为next函数的参数,从而获得对象的下一项,或者在没有其他项时引发StopIteration异常 。
- 可以作为iter函数的参数,并返回自身 。
反过来说,也成立:
- 任何可以传给iter而没有引发TypeError的对象都是可迭代对象 。
- 任何可以传给next而没有引发TypeError的对象都是迭代器 。
- 任何在传给iter时返回自身的对象都是迭代器 。
这是Python中的迭代器协议 。
迭代器无处不在
Python中的迭代器很多,例如:
>>> letters = ['a', 'b', 'c']>>> e = enumerate(letters)>>> e>>> next(e)(0, 'a')在Python3中,zip、map和filter对象也是迭代器 。
>>> numbers = [1, 2, 3, 5, 7]>>> letters = ['a', 'b', 'c']>>> z = zip(numbers, letters)>>> z>>> next(z)(1, 'a')Python中的文件对象也是迭代器 。
>>> next(open('hello.txt'))'hello worldn'在Python、标准库和第三方Python库中还有许多内置的迭代器 。
至此,已经可以给出完美的解释了 。
推荐阅读
- 一文详解Python异常处理
- 华德福教育在中国的现状—华德福教育理念的理解?
- 用户运营策略有哪些,谈谈关于营销对用户运营的理解
- T/T 电汇是什么意思和银行转账?电汇是什么意思? 如何理解?
- 李一桐|李一桐最新杂志图被吐槽,造型难看全靠脸撑,这样的时尚你能理解吗?
- 营销的概念如何理解,市场营销的本质及其含义
- 怎么理解数据化营销,盘点数据化营销对网店运营的作用
- 再认和回忆的区别。小学教师资格证如何理解再认与再现?
- 内容营销是什么意思,谈谈你们对内容营销的理解和认识
- 胡歌|前女友薛佳凝不离不弃,袁弘停工一年陪伴,胡歌:最理解我的心情
