一、生成器
生成器的本质就是迭代器
生成器的特点和迭代器一样。取值方式和迭代器一样(__next__(),send():给上一个yield传值)
生成器一般由生成器函数或者生成器表达式来创建
其实就是手写的迭代器
def func(): print("111") yield 222 ret = func() print(ret) # <generator object func at 0x0000028F2C062CA8>
因为函数中存在yield,那么这个函数就是一个生成器函数。这个时候我们在想执行函数就不再是执行函数了,而是获取这个生成器。
def func(): print("111") yield 222 gener = func() #这个时候函数不会执行,而是获取到生成器 ret = gener.__next__() #这个时候函数才会执行,yield的作用和return一样也是返回数据 print(ret) # 111 # 222
def func(): print("111") yield 222 print("333") yield 444 gener = func() ret = gener.__next__() print(ret) ret2 = gener.__next__() print(ret2) ret3 = gener.__next__() #最后一个yield执行完毕,再次__next__()程序报错,也就是说和return无关了 # Traceback (most recent call last): # 111 # 222 # 333 # 444 # File "F:/pythonworkspace/day13/day13练习.py", line 52, in <module> # ret3 = gener.__next__() # StopIteration
send和__next__()区别:
1.send和next()都是让生成器想下走一次
2.send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能使用send(),最后一次也不能使用。
二、生成器函数
和普通函数没有区别,里面有yield的函数就是生成器函数
生成器函数在执行的时候。默认不会执行函数体,返回生成器
通过生成器的__next__()分段执行这个函数
send()给上一个yield传值,不能在开头(没有上一个yield),最后一个yield也不可以用send()
三、推导式
用一句话来生成一个列表
lst = ["python"+str(j) for j in range(1,16)] print(lst)
语法:[结果 for循环 判断]
四、生成器表达式
生成器表达式和列表推导式的语法基本上是一样的。只是把[]替换成()
生成器表达式和列表推导式的区别:
1.列表推导式比较耗内存。一次性加载,生成器表达式几乎不占用内存,使用的时候才分配和使用内存。
2.得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器。
总结:推导式有,列表推导式,字典推导式,集合推导式,没有元组推导式
**生成器只有在要值得时候才拿值
def add(a, b): return a + b # 生成器函数 # 0-3 def test(): for r_i in range(4): yield r_i # 0,1,2,3 g = test() # 获取生成器 for n in [2, 10]: g = (add(n, i) for i in g) print(list(g)) #[20,21,22,23]