今天我们在进一步了解一下,生成器。
①:
1 def func(): 2 print('这是函数func') 3 return '函数func' 4 func()
结果是
这是函数func
②:
1 def func1(): 2 print('这是函数func1') 3 yield '函数func' 4 func1()
③:
1 def func1(): 2 print('这是函数func1') 3 yield '函数func' 4 print(func1())
结果:
<generator object func1 at 0x0000000002138E58> 返回的是func1的内存地址。
有没有发现这三个的值不一样。
那么 return 和yield 的区别是什么呢?
return是返回值,直接停止这个函数,
yield是分段停止这个函数。
1.生成器的本质就是迭代器
2.通过函数变成一个生成器
1 def func(): 2 print(1) 3 yield 5 # 我的函数走到这了 4 print(2) 5 yield 9 # 我的函数走到这了 6 7 g = func() # 生成一个生成器 8 9 print(g.__next__()) 10 print(g.__next__())
def func(): print(1) # return 5 yield 5 print(func().__next__()) # 这样生成一个生成器 print(func().__next__()) # 这样生成一个生成器 print(func().__next__()) # 这样生成一个生成器 print(func().__next__()) # 这样生成一个生成器
1 def func(): 2 print(1) 3 yield 5 # 我的函数走到这了 4 print(2) 5 yield 9 # 我的函数走到这了 6 7 g = func() # 生成一个生成器 8 print(g.__next__()) 9 print(g.__next__()) 10 11 碰到return就结束函数 12 碰到yield不结束就挂起 13 生成器的好处,非常节省内存
def func(): print(1) a = yield 2 # 1.挂起 2.返回值 3.接受值 print(a) # '123' print(3) b = yield 4 print(b) #'234' c = yield 9 g = func() print(g.__next__()) #1 2 g.send(None) print(g.send('123')) # send = next+传值 print(g.send('234')) # send = next+传值 # 第一次调用生成器的时候使用send里边的值必须是None
1 def func(): 2 yield 1 3 yield 2 4 5 g = func() 6 ret = g.__next__() 7 print(ret+4) 8 print(g.__next__())
2.yield from
1 def func(): 2 li = [1,2,3,4] 3 # yield li 4 yield from li #(= for yield in li) 5 6 ret = func() # 把生成器的地址给了ret 7 print('is ret',ret.__next__()) #一个生成器 8 print('is ret',ret.__next__()) 9 # 执行ret这个变量的指向的生成器地址: 10 print('is ret',ret) 11 # # 在全局空间找到一个变量叫做ret的,打印它的值 值就是生成器的地址
1 def func(): 2 li = [1,2,3,4] 3 l2 = [5,6,7,8] 4 # yield from li 5 # yield from l2 6 for i in li: 7 yield i 8 9 for em in l2: 10 yield em 11 # 12 ret = func() # 把生成器的地址给了ret 13 print('is ret',ret.__next__()) 14 print('is ret',ret.__next__()) 15 print('is ret',ret.__next__()) 16 print('is ret',ret.__next__()) 17 print('is ret',ret.__next__())
yield from li = for i in li
yield i
1 # 总结: 2 # 1.生成器的本质就是一个迭代器 3 # 2.生成器一定是一个迭代器,迭代器不一定是一个生成器 4 # 3.生成器是可以让程序员自己定义的一个迭代器 5 # 4.生成器的好处,节省内存空间 6 # 5.生成器的特性 一次性的,惰性机制,从上向下 7 # 6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None) 8 # 值必须是None,一般我建议你们使用__next__ 9 # 7. python2 iter() next() 10 # python3 iter() next() __next__() __iter__() 11 # 8.yield from 将可迭代对象元素逐个返回
3.推导式
一个容器包在最外面,结果,语法:
[结果,语法] #容器
1 # 列表推导式 2 li = [] 3 for i in range(10): 4 li.append(i) 5 print(li) 6 7 print([i for i in range(10)])
1 li = [] 2 for i in range(10): 3 if i%2 == 1: 4 li.append(i) 5 print(li) 6 7 print([i for i in range(10) if i%2 == 0]) # 过滤(筛选)
for循环的嵌套:
1 li = [] 2 for i in range(3): 3 for em in range(3): 4 li.append(em) 5 print(li) 6 7 # print([j for i in range(10) for em in range(3) for j in range(5)])
其字典、集合的推导式同列表推导式,没有元组推导式。
1 g = (i for i in range(10)) 2 print(g) 3 4 结果:<generator object <genexpr> at 0x0000000002168E58>