迭代器
原理非常类似Lua的泛型for。
for v in shit:print v#for的幕后逻辑如下;iterable = iter(shit) #生成对象的迭代器:iter()内置函数放回一个定义了__next__()方法的迭代对象v = next(iterable) #进行迭代:next()内置函数会调用__next__方法返回迭代数据。#当迭代完了,next会抛出StopIteration的异常来终止for循环。#了解了for的幕后逻辑,我们可以自定义可迭代对象,而不仅限于使用内置类型。class IterableObj:"""文档说明字符串"""def __init__(self, data):self.data = dataself.index = len(data)def __iter__(self): #iter(obj)触发并返回值return selfdef __next__(self): #next(obj)触发并返回值if self.index == 0:raise StopIterationself.index = self.index - 1return self.data[self.index]obj = IterableObj([1, 2, 3, 4, 5])for v in obj:print(v)#5#4#3#2#1
生成器:yield
Generator,用于生成迭代器。写法类似函数,但当它们要返回数据时会使用 yield 语句,yield的效果就是每次next(生成器)时,就会从上次离开位置回复执行。
相比于上面手写迭代器,本质上就是自动完成了这些工作:
- 自动创建方法
- iter() 和 next() 方法。
- 保存程序状态
- 类似lua的闭包
- 自动引发stopIteration
所以利用生成器,可以大大简化生成迭代器的工作。
def reverse(data):for index in range(len(data)-1, -1, -1):yield data[index]for char in reverse('golf'):print(char)
生成器表达式
类似列表推导式。
sum(i*i for i in range(10)) #285xvec = [10, 20, 30]yvec = [7, 5, 3]sum(x*y for x,y in zip(xvec, yvec)) #260from math import pi, sinsine_table = {x: sin(x*pi/180) for x in range(0, 91)}unique_words = set(word for line in page for word in line.split())valedictorian = max((student.gpa, student.name) for student in graduates)data = 'golf'list(data[i] for i in range(len(data)-1, -1, -1)) #['f', 'l', 'o', 'g']
