流畅的Python
可迭代的对象、迭代器和生成器
python2.2开始引入yield关键字
迭代器从集合中取出元素,生成器用于“凭空”生成元素。
解释器需要迭代对象x时,会自动调用iter(x)。
- 检查对象是否实现了__iter__()方法,如果实现就调用它产生一个迭代器
- 如果实现了__getitem__()方法,Python就创建一个迭代器,尝试按顺序(从索引0开始)按顺序获取
- TypeError。“C object is not iterable”,C是对象所属的类。
Python3.4开始,检验对象x是否可以迭代:iter(x)
Python从可迭代对象中获取迭代器。
迭代器到头会抛出StopIteration异常,Python内置的已经处理了。如果是自己写迭代器话,需要处理这个异常。也只有这个办法,不能检查是否有遗留元素。
|
|
标准迭代器接口:
__next__()方法:
返回下一个可用的元素,如果没有就抛出StopIteration。
__iter__()方法:
返回self。
迭代器可以迭代,但是可迭代对象不是迭代器。
迭代器模式
访问一个聚合对象的内容而无需暴露它的内部表示
支持对聚合对象的多种遍历
为遍历不同的聚合结构提供一个统一的接口(多态迭代)。
必须能从同一个可迭代的实例中获取多个独立的迭代器,而且每个迭代器要能维护自身的内部状态。
但是,用一个新的类太不Python了,所以常用生成器函数。
生成器函数:有yield
关键字。
调用生成器函数时,会返回一个生成器对象。
|
|
lazy evaluation and eager evalution
`懒惰求值和及早求值。
re.finditer函数是
re.findall`的惰性版本。
|
|
生成器表达式(语法糖
使用列表推导式的时候,它迫不及待地推导出结果。而生成器表达式只在要生成的时候才生成。
|
|
如何判断:如果是生成器表达式需要分行写,就倾向于生成器函数。另外生成器函数可以复用。
@优雅
|
|
itertools模块
|
|