Python小知识点——生成器(generator)与关键字yield的运用

生成器(generator)是一种可迭代对象。

在处理包含大量数据时,如果使用list来进行操作,那么内存占用大,效率低。生成器通过延迟计算,实现了一种边循环边计算的可能,只有在需要的时候才返回相应的结果,而不是一次性返回一整个结果列表,因此可以有效地节省了大量的空间。

首先,根据列表生成式,将[]改成()即可创建一个generator

>>> a = (x * x for x in [1,2,3])  # 列表生成式:a = [x * x for x in [1,2,3]]

如果你想转成list类型,可以直接用list(a)。

输出元素,可以使用next()

>>> next(a)
1
>>> next(a)
4
>>> next(a)
9

每一次调用next(a),a就会循环一次并计算一次。当循环完全部元素后,再调用next(a),就会报错。

另外,因为生成器本身是可迭代对象,所以你也可以使用for in 循环遍历直接输出结果。

>>> for x in a:
	print(x)	
1
4
9

对生成器有了初步认识后,我们就可以开始掌握关键字yield了。

其实很简单,关键字yield的作用就是替代关键字return,如果一个函数中使用了yield来返回结果,我们就认为这个函数是一个生成器。

def func(n):
    for i in range(1,n):
        result = i * i
        yield result

这部分由yield返回结果的函数,有和生成器一样的功能(因为这些函数也是生成器,就好像这支笔和这支笔有一样的功能)。

了解生成器(generator)与关键字yield的知识后

我们将上面的代码扩展一下

def func(n):
    for i in range(1,n):
        result = i * i
        yield result
 
func = func(5)
for x in func:
    print(x)
for x in func:
    print(x)

如果你运行了这个代码,突然奇怪的事情就发生了…

>>> 
1
4
9
16

明明是安排了两个循环,却只输出了一次循环。如果你在两个循环中间,添加一个print(list(func))语句,你就会发现由generator转换成list的func是空的,即func=[],func内部的元素就突然消失了!

这就涉及到使用生成器必须要注意的一点:一个生成器只能遍历一次!

为什么会这样呢?其实在调用next()方法的时候就大概明白了,每一次调用next()的时候,循环处于启动状态,不调用的时候,程序就处于一种“暂停”的状态,直到再次被调用,才会“播放”。当循环到最后一个元素后,我们再调用next()时就会报错。这说明了生成器只是代表了一次完整的循环中不断计算结果的过程。

那如果你还是希望能让你的生成器能被多次调用的话,你可以这样做

1、将生成器转换成list,再进行遍历

func = list(func(5))

2、需要遍历几次,就生成多少个可迭代对象(generator),再分别遍历

func1 = list(func(5))
func2 = list(func(5))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值