生成器

生成器的三种方式:

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]

原文地址:https://www.cnblogs.com/qj696/p/10720136.html