Python|Python 生成器
生成器
目录
- 生成器
- 1. 什么是生成器
- 2 创建生成器
- 3 生成器练习
- 4 yield和return的区别
- 5 生成器和迭代器总结
- 6. 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
传值使用
send
给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__()# 执行结果:
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
- 可以返回值(支持多个,并且组织成元组)
- 函数体代码遇到yield不会结束而是阻塞
- yield可以将函数变成生成器 并且还支持外界传值
return
- 可以返回值(支持多个并且组织成元组)
- 函数体代码遇到return直接结束
迭代器对象 生成器对象 我们都可以看成是"工厂",只有当我们所要数据的时候工厂才会加工出"数据"
主要目的就是节省空间
6. Python中内置函数
【Python|Python 生成器】
文章图片
内置函数
https://docs.python.org/zh-cn/3/library/functions.html
推荐阅读
- 急于表达——往往欲速则不达
- 布丽吉特,人生绝对的赢家
- 第三节|第三节 快乐和幸福(12)
- Y房东的后半生14
- 赢在人生六项精进二阶Day3复盘
- 学无止境,人生还很长
- 我错了,余生不再打扰
- 牛人进化+|牛人进化+ 按自己的意愿过一生
- 别怪生活,自己作的!
- 人生两件宝(好身体,好心情!)