生成器与迭代器
1.概念解释
list_a= [i for i in range(10)] # 列表推导式
g = (i for i in range(10)) # 生成器表达式
迭代(iteration):在一个可迭代对象中依次取出元素的过程, 可理解为遍历。
可迭代对象(Iterable): 实现了迭代器协议的对象。可以通过for i in x的形式获取元素,定义了__iter__方法。 如基础数据类型中的:list、tuple、dict、set、str,以及迭代器生成器等。
如python中的 str list tuple,dict, xx可迭代对象可以通过iter(xx)函数产生迭代器对象
迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象称为迭代器。实现了__iter__及__next__方法的对象。
迭代器协议:对象需要提供next()方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。
生成器(generator):python有一种“一边遍历一遍计算值”的方式产生可迭代对象,这就是生成器。生成器是一种特殊的迭代器,返回结果用yield关键字在运行时产生,前期不占内存,解决列表推导式占额外内存的问题。可以通过send()函数给生成器发信
2.如何判断一个对象是可迭代对象和生成器?
from collections import Iterable # 可迭代对象
isinstance(xx,Iterable)
from collections import Generator #生成器
a = (i for i in range(10))
ret = isinstance(a,Generator)
print(ret)
3.从itertools中导入一些常用迭代器,如
1)count为计数器, count(start=1,step=3), 没有上限。
from itertools import count
counter = count(3,2) #产生一个以3开始,步长为2的无限序列
next(counter)
next(counter)
next(counter)
2)cycle将一个有限序列变为一个无限序列
week_days = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
cycle_week = cycle(week_days)
for i in range(10):
print(next(cycle_week))
3)islice从一个无限序列中提取出一个有限序列
islice(obj, start,stop,step)
class Fib:
def __init__(self):
self.left = 0
self.current = 1
def __iter__(self):
return self
def __next__(self):
value = self.current
self.left, self.current = self.current, self.current + self.left
return value
from itertools import islice
f = Fib()
print(list(islice(f, 11, 40)))
4.生成器举例
def myFunc():
# return 1 #一般函数
a =1
while True:
yield a # 第一次执行 从99行返回了
a +=2 # 下一次执行也从这里开始
print('hello world!')
f = myFunc()
print(next(f))
print(next(f))
可以用send方法,改变函数的步长
def generater(start, end, step):
while (start <= end):
r = yield start
if isinstance(r, int):
step = r
start += step
else:
raise StopIteration
a = generater(0, 100, 1)
for i in range(3): #产生3个数值,每次加+1
print(next(a))
print(a.send(4)) #产出3个数值,每次加+4
print(next(a))
print(next(a))