前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于生成器和yield的执行过程

关于生成器和yield的执行过程

作者头像
y191024
发布2022-09-20 18:57:44
2510
发布2022-09-20 18:57:44
举报
文章被收录于专栏:睡不着所以学编程

什么是生成器?

在Python中,一边循环一边计算的机制,称为生成器(generator),可以大大的节省内存空间

如果得到一个生成器呢?

代码语言:javascript
复制
# 这是列表推导式
list1 = [x for x in range(10)]
print(list1)

而想要得到一个生成器,只要将两边的“[]”换成“()”即可

代码语言:javascript
复制
g = (x*3 for x in range(10))
print(type(g)  # <class 'generator'> 得到的类型是生成器
print(g)
#<generator object <genexpr> at 0x000001DF35D5BDD0>

但是当我们想要把生成器里的数字打印出来时,会出现一串内存地址。

如果我们想得到生成器中的数字,我们需要调用它,有两种方法。 1.__next__()方法

代码语言:javascript
复制
print(g.__next__())  # 0
print(g.__next__())  # 3
print(g.__next__())  # 6

2.next()函数

代码语言:javascript
复制
print(next(g))  #9

yield的作用

1. 只要函数中有yield,那么函数就变成了生成器

代码语言:javascript
复制
def func():
    n = 0
    while True:
        n += 1
        yield n  # yield 相当于将n返回给g + 暂停
g = func()
print(g.__next__())
>>>1

下面来一道实例:生成斐波那契数列。 斐波那契数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…… 这个数列从第3项开始,每一项都等于前两项之和。

代码语言:javascript
复制

def fib(length):
    a = 0
    b = 1
    n = 0
    while n < length:
        a, b = b, a + b
        yield b
        n += 1  # 下一次调用从此处开始执行
    return "超过次数!"
    # 会返回给报错原因stop iteration中 (StopIteration: 超过次数!)


result = fib(8)
print(result.__next__())
print(result.__next__())
print(result.__next__())
print(result.__next__())
print(result.__next__())

# 调用超过length的次数将会报错
打印结果:
1
2
3
5
8

下面我将贴出一个例子,并分析它的执行过程。

代码语言:javascript
复制
#这是原代码
def foo():
    n = 0
    while True:
        temp = yield n
        print("temp", temp)
        n += 1
# 调用
f = foo()
foo1 = f.send(None)
print("foo1:", foo1)
foo2 = f.send("foo2") #send函数相当于给yield传值
print("foo2:", foo2)

第一轮分析:

在第②步中,代码并不会执行函数的部分,由于函数中yield出现,因此会直接跳到第③步

第二轮:

代码语言:javascript
复制
最后的结果:
foo1: 0
temp foo2
foo2: 1

有一个要注意的地方就是为什么第一次要send(None)呢?* 由于第一次还没有进入到循环中,无法将值传给yield,因此会报错,如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 睡不着所以学编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档