生成器
我自己想写个可迭代的,——生成器
生成器的本质就是迭代器
因此生成器的所有好处都和迭代器一样
但是生成器是我们自己写的python代码
生成器的实现有两种方式:
1.生成器函数
2.生成器表达式
def func(): return ['衣服1','衣服2000000'] ret = func() print(ret) def g_func(): yield 1 g = g_func() print(g) # <generator object g_func at 0x00000000006AAFC0> generator 生成器 ---> 迭代器 print('__iter__' in dir(g)) # True print('__next__' in dir(g)) # True print(g.__next__()) # 1
生成器函数和普通函数之间的区别
生成器函数中含有yield关键字
生成器函数调用的时候不会立即执行,而是返回一个生成器
def g_func(): print('aaaa') yield 1 print('bbbb') yield 2 g = g_func() for i in g: print(i) # print(g.__next__()) # print(g.__next__()) def cloth(): for i in range(1000000): yield '衣服%s'%i g_cloth = cloth() print(g_cloth.__next__()) print(g_cloth.__next__())
监听文件末尾追加的例子
def tail(): f = open('文件',encoding='utf-8') # print('__iter__' in dir(f)) # True # print('__next__' in dir(f)) # True f.seek(0,2) while True: line = f.readline() if line: yield line import time time.sleep(0.1) g = tail() for i in g: print(i)
send的用法
def func(): print('*'*10) a = yield 5 print('a :',a) yield 10 g = func() num = g.__next__() print(num) num2 = g.send('alex') # 相当于next,但是会传值给yield前的变量 print(num2)
send:从哪一个yield开始接着执行,就把一个值传给了哪个yield
send不能用在第一个触发生成器
生成器函数中有多少个yield就必须有多少个next+send
计算移动平均值
def init(func): # 生成器的预激装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) g.__next__() return g return inner @init def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/count g_avg = averager() # next(g_avg) # g_avg.__next__() print(g_avg.send(10)) print(g_avg.send(30)) print(g_avg.send(5))
yield from
def func(): a = 'AB' b = 'CD' yield from a # 接收一个可迭代对象,相当于下面的for,python3特有 # for i in a: # yield i yield from b # for j in b: # yield j g = func() for i in g: print(i)
生成器函数:生成一个生成器的函数
生成器的本质才是迭代器
生成器函数的特点:
带有yield关键字,且调用之后,函数内的代码不执行
触发执行的方式:
next
send send(None) == __next__()
for循环
生成器表达式
y = [1,2,3,4,5,6,7,8] g = (i**2 for i in y ) print(g) # <generator object <genexpr> at 0x00000000006AAFC0> print(list(g)) # [1, 4, 9, 16, 25, 36, 49, 64] # for i in g: # print(i) l = ['鸡蛋%s'%i for i in range(10)] print(l) laomuji = ('鸡蛋%s'%i for i in range(10)) for egg in laomuji: print(egg)
面试题
def demo(): for i in range(4): yield i g=demo() g1=(i for i in g) g2=(i for i in g1) print(list(g1)) # [0, 1, 2, 3] print(list(g2)) # []
def add(n,i): return n+i def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) # n = 1 # g=(add(n,i) for i in test()) # n = 10 # g=(add(10,i) for i in (add(10,i) for i in test())) print(list(g)) # [20, 21, 22, 23]