python cook 2
迭代器 iterator 生成器 generator
1、手动遍历迭代器
2、代理迭代
解释:将迭代操作代理到容器内部的对象上
操作:使用__iter()__, for 循环遍历对象时,会自动调用类特殊成员方法__iter()__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Foo(object): 2 3 def __init__(self, sq): 4 self.sq = sq 5 6 def __iter__(self): 7 return iter(self.sq) 8 9 obj = Foo([11,22,33,44]) 10 11 for i in obj: 12 print i
3、使用生成器创建新的迭代模式
生成器也是一种可迭代的对象
函数内使用了yeild ,则该函数就变成了一个生成器
生成器只能用于迭代操作 ,如 next()
for 循环 是一种迭代操作,其内部调用了next()
for循环语法内部做了什么?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 obj = iter([11,22,33,44]) 2 3 while True: 4 val = obj.next() 5 print val
4、实现迭代器协议
略
5、反向迭代
列表或字典等可以使用reversed()进行反向迭代;
自定义对象内部实现了__reversed__()__的特殊方法时,可以使用reversed(obj),反向迭代生效。
6、带有外部状态的生成器函数
自定义一个类,把生成器函数放到__iter__()方法中,例如
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from collections import deque class linehistory: def __init__(self, lines, histlen=3): self.lines = lines self.history = deque(maxlen=histlen) def __iter__(self): for lineno, line in enumerate(self.lines, 1): self.history.append((lineno, line)) yield line def clear(self): self.history.clear()
7、迭代器切片
使用 itertools.islice(iterator,start,end) 来对迭代器和生成器切片,返回一个可迭代的 islice 对象,同时 原来的迭代器会被消耗
如果需要之后再次访问这个迭代器,记得先把它里面的数据放入一个列表中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def count(n): 2 while True: 3 yield n 4 n += 1 5 c = count(0) 6 7 imort itertools 8 for i in itertools(c,0,3) 9 print(i) 10 >0 11 >1 12 >2
8、跳过可迭代对象的开始部分
itertools.dropwhile(func,itertor) 每次迭代的值会传入func,当func返回值为True时,丢弃该值,直到func返回值为false时,停止判断返回后面所有的值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 a.txt 前三行为注释 2 #111111 3 #222222 4 #333333 5 aaaaaaaa 6 bbbbbbbb 7 去掉注释 8 import itertools 9 with open('a.txt') as f: 10 for i in itertools.dropwhile(lambda line:line.startswith('#'),f): 11 print(i) 12 13 >>aaaaaaaa 14 15 >>bbbbbbbb
9、排列组合的迭代
10、序列上索引值迭代
11、同时迭代多个序列
12、不同集合上元素的迭代
13、创建数据处理管道
14、展开嵌套的序列
判断元素可迭代后,递归yield生成器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from collections import Iterable 2 def flatten(items,ignore_type=(str,bytes)): 3 4 for i in items: 5 6 if isinstance(i,Iterable) and not isinstance(i,ignore_type): 7 8 yield from flatten(i) 9 10 else: 11 12 yield i 13 14 15 a=[1,2,[3,4,[5,6],7,8],9] 16 17 for i in flatten(a): 18 print(i)
15、顺序迭代合并后的排序迭代对象
16、迭代器代替while无限循环