迭代器
from collections.abc import Iterable,Iterator
isinstance(list(),Iterable)
isinstance(list(),Iterator)
Iterable 可迭代
1. 可用for loop实现访问
2. 常见的list,tuple,dict,set,str
4. 使用iter()后生成迭代器,也可以用next()访问
5. 可迭代包含迭代器:即Iterable包含Iterators
Iterators 迭代器
1. 定义:
* 迭代中可以记忆自己的状态
* 有__next__方法
* 自动跳到下一个值
* 在下一个值时更新状态
* 结束时信号会raise StopIteration异常
* 可用try...except来处理
* 可自己迭代的,会有__iter__方法,即迭代器
2. 生成迭代器iterators.__iter__()
1. 如果可迭代的话,则获得迭代器
2. 如果不可迭代的话,则通过索引生成迭代器
3. 若均不满足,就raise TypeError
* 可用try...except来处理
3. 迭代协议
1. __iter__()
2. __next__() 调用next()可以不断指向下一个值
3. 所有可迭代的都可以用内置函数 iter()获得迭代器,之后可以使用next()
* 常见的list,tuple,dict,set,str,均是Iterator的子类
* open读取后,可以用next调用
4. 为什么要用迭代器
1. lazy:不用考虑下一个是什么,自动next
2. 有时节省时间和内存,相对list等数据结构(见例题)
3. 可以生成无穷长的迭代器,且占用内存很小
怎样制造迭代器
1. 对象导向的生成器
* 可以自建一个class
* 包含__init__ \ __iter__\ __next__(见例子)
2. 生成器函数
* 可以自建一个def,当called时,会返回迭代器但不会立即运行
* 可以做一个无穷的迭代器函数,要比对象导向的更简洁
* 包含yield语句,收集元素,并返回一个generator对象,即迭代器
* yield语句可以是一个或多个,通过for循环,按顺序收集迭代值(见例子)
3. 生成器的表达式
* 自建一个类似list的表达式 (x for x in L)
* 类似于for loop加append
* 比生成函数更简洁
总结
1. 迭代器和可迭代的共性是:
可迭代中有getitem,迭代中是有next
3. 不同生成器的简洁性:表达式 > 函数 > 表达式
4. return 和yield的比较
* return
函数的终点、返回值或者None、摧毁了所有的局部变量
* yield
暂停函数的执行、获取值不摧毁局部变量、之后会从停下来的地方接着运行