前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >彻底搞懂Python中yield 关键字

彻底搞懂Python中yield 关键字

原创
作者头像
mr.songw
修改2021-01-22 10:52:42
1.1K0
修改2021-01-22 10:52:42
举报
文章被收录于专栏:Python 自习室Python 自习室
普通函数和 generator 函数的区别

假如要创建一个返回奇数数列的函数,普通函数的做法如下:

代码语言:txt
复制
def odd_numbers(n):
    odd_num_list = []
    for i in range(n):
        if (i % 2) == 1:
            odd_num_list.append(i)

    return odd_num_list


for j in odd_numbers(10):
    print(j)

输出

代码语言:txt
复制
1
3
5
7
9

当将上述函数改成如下形式时,普通函数便变成了一个 generator 函数。这时候调用 odd_numbers(10) 不会执行 odd_numbers 函数,而是返回一个 generator 对象。

代码语言:txt
复制
def odd_numbers(n):
    for x in range(n):
        if (x % 2) == 0:
            yield x


num = odd_numbers(10)
print(num)

输出

代码语言:txt
复制
<generator object odd_numbers at 0x7f9d77a095f0>
从 generator对象获取值

为了从 generator 对象获取值,我们可以使用 for loopnext() 或者 list() 方法。

for loop 方法:

代码语言:txt
复制
def odd_numbers(n):
    for x in range(n):
        if (x % 2) == 1:
            yield x


num = odd_numbers(10)
for i in num:
    print(i)

输出

代码语言:txt
复制
1
3
5
7
9

next() 方法:

代码语言:txt
复制
def odd_numbers(n):
    for x in range(n):
        if (x % 2) == 1:
            yield x


num = odd_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

输出

代码语言:txt
复制
1
3
5
7
9

list() 方法

代码语言:txt
复制
def odd_numbers(n):
    for x in range(n):
        if (x % 2) == 1:
            yield x


num = odd_numbers(10)
for i in list(num):
    print(i)

输出

代码语言:txt
复制
1
3
5
7
9

当我们使用 for loopnext() 或者 list() 方法获取 generator 对象的值时,每次循环都会执行 odd_numbers()函数的代码,执行到 yield x 时,就会返回一个值,下一次执行时,从 yield x 的下一条语句继续执行,函数的状态和上次中断执行前是一样的,于是继续执行,直到再次遇到 yield x

generator 对象只能被遍历一次

generator 对象只能被遍历一次,当我们再次使用时, generator 对象为空。

代码语言:txt
复制
def odd_numbers(n):
    for x in range(n):
        if (x % 2) == 1:
            yield x


num = odd_numbers(10)
for i in num:
    print(i)

# 再次使用 num
print(list(num))

输出

代码语言:txt
复制
1
3
5
7
9
[]

从输出中可以看出,当再次使用 num 时,num 变成了空。

yield vs. return

包含 yield 的函数在被调用时,返回一个 generator 对象给调用者,只有在遍历对象时,函数的代码才会被执行。而函数中的 return 返回一个值给调用者。

yield

return

包含 yield 的函数在被调用时,返回一个 generator 对象给调用者,只有在遍历对象时,函数的代码才会被执行

return 返回一个值给调用者

不占用内存

需要给返回的值分配内存

适合处理数据量比较大的情况

当处理的数据量较小时,比较方便

当数据量较大时,性能较好

当数据量较大时,由于需要使用大量内存,会拖慢性能。

总结
  • return 关键字返回一个值给调用者不同的是,包含 yield 关键字的函数返回一个 generator 对象给调用者。
  • 返回的 generator 对象在使用过一次后便不再可以使用,如果要获取值,需要遍历 generator 对象。
  • 可以使用 for loopnext() 或者 list() 方法从 generator 对象获取值。
  • yieldreturn 的最大区别是,yield 返回一个 generator 给调用者,而 return 返回一个值给调用者。
  • 使用 yield 时,不会将值存储在内存中,这在处理的数据量很大时,比较有优势。

封面图:该图片由FelixMittermeier在Pixabay上发布

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 普通函数和 generator 函数的区别
  • 从 generator对象获取值
  • generator 对象只能被遍历一次
  • yield vs. return
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档