Python中,所有的集合都可以迭代。在语言内部中,迭代器主要用于:
- for循环
- 构建和扩展集合类型
- 逐行遍历文件文本
- 列表推导,字典推导跟集合推导
- 元组拆包
- 调用函数时,用*拆包实参
序列可以迭代的原因: iter函数
解释器需要迭代对象x时,会自动调用iter(x).
内置的iter函数有以下作用:
- 检查对象是否实现了
__iter__
方法,如果实现了就调用它,获取一个迭代器. - 如果没有
__iter__
方法,寻找__getitem__
方法,尝试按照顺序(index为0开始)获取元素. - 如果都没有,python抛出TypeError异常.提示"x object is not iterable
. x为目标对象所属的类. 在白鹅类型理论中,可迭代对象的定义更为简单,实现了
iter方法即可.因为
abc.Iterable类实现了
subclasshook`方法。
标准的迭代器接口有两个方法
__next__
: 返回下一个可用的元素。如无,则抛出StopIteration异常。在collections.abc.Iterator
抽象基类中定义。继承自Iterable
类.
__iter__
: 返回self,以便在应该使用可迭代对象的地方使用迭代器。例如for循环中。定义在Iterable
类中.
迭代器定义
迭代器是这样的对象:实现了无参数的__next__
方法,返回序列中的下一个元素,如没有元素了,就抛出StopIteration异常.
Python中的迭代器还实现了__iter__
方法,所有迭代器也可以迭代.
可迭代对象与迭代器的对比
python从可迭代对象中获取迭代器。
要知道
- 可迭代对象有个
__iter__
方法,每次都实例化一个新的迭代器; - 而迭代器要实现
__next__
方法,返回单个元素,还要实现__iter__
方法,返回迭代器本身。
因此,迭代器可以迭代,但是可迭代对象不是迭代器。
两个结论: - 可迭代的对象一定不能是自身的迭代器,也就是说,可迭代的对象必须实现
__iter__
方法,但不能实现__next__
方法 - 另一方面,迭代器应该一直可以迭代,所有迭代器的
__iter__
方法应该返回自身。
生成器函数
生成器函数的工作原理
只要python函数的定义体中有yield关键字,该函数就是生成器函数。
生成器表达式
可以理解为列表推导的惰性版本。是制造生成器的工厂。
何时使用生成器表达式
当生成器函数比较简单时。
python中的自带生成器函数。
- 用于过滤
- 用于映射
- 合并多个可迭代对象
- 用于重新排列元素的生成器函数
新语法 yield from
如果生成器函数需要产出另一个生成器生成的值,传统方法是使用嵌套的for循环.
yield from 其实就是代替了内部的for循环.获取到内部生成器产生的值
常用在协程上。
可迭代的归约函数
image.png深入分析iter函数
可以传入两个参数。第一个参数必须是可调用的对象,用于不断调(该对象没有参数), 产出各个值,第二个值可以看做是个终止条件,当第一个参数对象调用返回改值时。迭代器抛出StopIteration异常。停止迭代。
网友评论