生成器的三种方式:
1.通过函数生成。
#函数
def func()
print("111")
return 222
ret = func()
print(ret)
结果:
111
222
#将函数中的return 换成yield 就是生成器
def func()
print('111')
yield 222
ret = func()
print(ret)
结果:<generator object func at 0x10567ff68>
注:ret = func() 是一个生成器打印出来的是生成器地址。只有在.__nex__( )的方法下能打印出111 222
当打印第三个.__next__( ) 时会报错。
2.通过推导式来实现生成器。
注意圆括号
gen = (i for i in range(10))
print(gen)
结果:
<generator object <genexpr> at 0x106768f10>
3.通过数据转换也可以生成生成器。
send 和 next()都是让生成器向下走一次
send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码时使用
.__next__() 或send(None)
生成器可以使用for循环来循环获取内部元素:
def func():
print(111)
yield 222
print(333)
yield 444
print(555)
yield 666
gen = func()
for i in gen:
print(i)
结果:
111
222
333
444
555
666
⽣成器表达式和列表推导式的区别:
1. 列表推导式比较耗内存. ⼀次性加载. ⽣成器表达式⼏乎不占⽤内存. 使⽤的时候才分配和使⽤内存
2. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个生成器。
⼀个⾯试题. 难度系数500000000颗星
def add(a, b):
return a + b
def test():
for r_i in range(4):
yield r_i
g = test()
for n in [2, 10]:
g = (add(n, i) for i in g)
print(list(g))
把for循环拆开分析
n=2
g = (add(n, i) for i in g)#注意 这里并不执行代码 而是记录代码
n=10
g = (add(n, i) for i in g)#这里的第二个g,已经替换成n=2时的g = (add(n, i) for i in g)
即
n=2
g = (add(n, i) for i in g)#注意 这里并不执行代码 而是记录代码
n=10
g = (add(n, i) for i in (add(n, i) for i in g))#这里的第二个g,已经替换成n=2时的g = (add(n, i) for i in g)
即
def add(a, b):#a+b
return a + b
def test():#0-3
for r_i in range(4):
yield r_i
g = test()#函数不执行,获取到的是生成器
n=10
g = (add(n, i) for i in (add(n, i) for i in g))
print(list(g))#函数开始执行
》》》[20, 21, 22, 23]