Python 笔记(11)— 生成器(通过表达式和函数分别创建 generator)

本文详细介绍了Python中生成器的概念,包括如何通过列表生成式和函数创建生成器,以及生成器的工作原理。生成器允许在循环过程中动态计算元素,节省大量内存空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含 100 万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。

Python 中,这种一边循环一边计算的机制,称为生成器 generator

要创建一个 generator,有以下几种方法:

1. 通过表达式创建生成器

只要把一个列表生成式的 [] 改成 (),就创建了一个 generator

In [41]: g = (x for x in range(3))

In [42]: type(g)
Out[42]: generator

In [43]: g.next()
Out[43]: 0

In [44]: g.next()
Out[44]: 1

In [45]: g.next()
Out[45]: 2

In [46]: g.next()
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-46-d7e53364a9a7> in <module>()
----> 1 g.next()

StopIteration: 
'''
每次调用 next(),就计算出 g 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误
'''

因为生成器是可迭代的,所以可以通过循环来获取每一个值。但是你只可以迭代他们一次,不能重复迭代,因为它并没有把所有值存储在内存中,而是实时地生成值:

In [18]: g = (x for x in range(3))

In [19]: for i in g:
    ...:     print i
    ...:     
0
1
2
# 再一次迭代时显示的是空值
In [20]: for i in g:
    ...:     print i
    ...:   
        
        

2. 通过函数来创建生成器

如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generatorgenerator 和函数的执行流程不一样。

  • 函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回;
  • generator 的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。
In [21]: def gen():
    ...:     for i in range(3):
    ...:         yield i
    ...:         

In [22]: g = gen()

In [23]: g.next()
Out[23]: 0

In [24]: g.next()
Out[24]: 1

In [25]: g.next()
Out[25]: 2

In [26]: g.next()
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-26-d7e53364a9a7> in <module>()
----> 1 g.next()

StopIteration: 

In [27]: g
Out[27]: <generator object gen at 0x0000000003BA0240>

In [28]: gen
Out[28]: <function __main__.gen>

In [29]: gen()
Out[29]: <generator object gen at 0x0000000003BA01B0>

有关 yield 函数的用法,可以参考 https://blog.youkuaiyun.com/wohu1104/article/details/104533897

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值