Python|Python 生成器

生成器
目录

  • 生成器
    • 1. 什么是生成器
    • 2 创建生成器
    • 3 生成器练习
    • 4 yield和return的区别
    • 5 生成器和迭代器总结
    • 6. Python中内置函数

Python|Python 生成器
文章图片

1. 什么是生成器
生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值。
2 创建生成器
生成器可以通过生成器表达式和生成器函数获取到
生成器表达式
创建生成器对象和创建列表生成式特别像
# 创建列表生成式 >>> list_num = [x for x in range(10)] >>> list_num [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 生成器 >>> glist_num = (x for x in range(10))# 只需要把中括号换成小括号就成了生成器 >>> glist_num at 0x7fc3d7375830> >>> glist_num.__next__() 0 >>> glist_num.__next__() 1 >>> next(glist_num) 2 >>> next(glist_num) 3# 生成器表达式内部的代码只有在迭代取值的时候才会执行

使用next()和使用__next__()一样
生成器函数
生成器函数指的是函数体中包含yield关键字的函数
定义生成器函数和定义普通函数一样。
# 1 生成器函数 >>> def my_func(): print("Hello") yield >>> my_func() >>> res = my_func() >>> res >>> next(res) Hello >>> >>> next(res) Traceback (most recent call last): File "", line 1, in StopIteration# 生成器函数(yield有返回值)def my_func(): print("Hello") yield 1res = my_func()r = res.__next__()# 会执行 print("Hello")print(r)# r为yield的返回值# 执行结果: Hello 1# 生成器函数(yield多个返回值) def my_func(): print("Hello") yield 1,2res = my_func()r = res.__next__()print(r)# 执行结果: Hello (1, 2)#函数中只有一个yield所以只能执行一次__next__()方法 def my_func(): print("Hello") yield 1,2res = my_func()print(res.__next__()) print(res.__next__())# 调用两次就会报错#执行结果: Hello (1, 2) Traceback (most recent call last): File "b.py", line 8, in print(res.__next__()) StopIteration# 有多个yield def my_func(): print("Hello") yield 1,2 print("world") yield 'a','b' res = my_func()print(res.__next__()) # 每执行一个__next__代码往下运行到yield停止 返回后面的数据 print(res.__next__()) # 每执行一个__next__代码往下运行到yield停止 返回后面的数据

注意:当函数体内含有yield关键字 那么在第一次调用函数的时候,并不会执行函数体代码,而是将函数变成了生成器(迭代器).
每执行一个__next__代码往下运行到yield停止 返回后面的数据.
yield不但能返回值,而且还能给它传值
yield传值
使用sendyield传值
示例:
def my_define(name): print("%s is doing work" % name) while True: play= yield print("%s is do %s" %(name, play))res = my_define("Hans")res.__next__() res.__next__()# 执行结果: Hans is doing work Hans is doing None# 给yield传值: def my_define(name): print("%s is doing work" % name) while True: play= yield print("%s is do %s" %(name, play))res = my_define("Hans")res.__next__() res.__next__() # 给yield传两个值:write和coding res.send("write") res.send("coding")# 执行结果: Hans is doing work Hans is do None Hans is do write Hans is do coding

3 生成器练习
模拟range功能
# 代码 def my_range(start, stop=None, step = 1): if not stop: stop = start start = 0while start < stop: yield start start += stepprint("一个参数") for i in my_range(3): print(i)print("两个参数") for i in my_range(1,3): print(i)print("三个参数") for i in my_range(1, 10, 2): print(i) # 执行结果: 一个参数 0 1 2 两个参数 1 2 三个参数 1 3 5 7 9

求和(面试题)
# 代码: def add(n, i): return n + idef test(): for i in range(4): yield i g = test() for n in [1, 10]: g = (add(n, i) for i in g)res = list(g) print(res)#从下面的结果中选择一个:#A. res=[10,11,12,13] #B. res=[11,12,13,14] #C. res=[20,21,22,23] #D. res=[21,22,23,24]# 解析: 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) """ 第一次for循环 g = (add(n, i) for i in g) 第二次for循环 g = (add(10, i) for i in (add(10, i) for i in g)) """ res = list(g) print(res)#执行结果为:[20,21,22,23], 答案选C #A. res=[10,11,12,13] #B. res=[11,12,13,14] #C. res=[20,21,22,23] #D. res=[21,22,23,24]

4 yield和return的区别
yield
  1. 可以返回值(支持多个,并且组织成元组)
  2. 函数体代码遇到yield不会结束而是阻塞
  3. yield可以将函数变成生成器 并且还支持外界传值
return
  1. 可以返回值(支持多个并且组织成元组)
  2. 函数体代码遇到return直接结束
5 生成器和迭代器总结
迭代器对象 生成器对象 我们都可以看成是"工厂",只有当我们所要数据的时候工厂才会加工出"数据"
主要目的就是节省空间
6. Python中内置函数
【Python|Python 生成器】Python|Python 生成器
文章图片

内置函数
https://docs.python.org/zh-cn/3/library/functions.html

    推荐阅读