首页 > 编程语言 >对python生成器的理解

对python生成器的理解

时间:2023-06-14 13:01:26浏览次数:48  
标签:... 函数 generator python 生成器 yield next step 理解

什么是生成器?

yield

image
image
该函数没有运行而是返回了一个对象
image
image
生成器是迭代器
需要满足迭代器协议
image

yield对函数做了什么

image
image
image

和class定义的迭代器进行对比

image

创建生成器

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator

L = [x * x for x in range(10)]
L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g = (x * x for x in range(10))
g
<generator object at 0x1022ef630>

生成器如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值,但正确的方法是使用for循环,因为generator也是可迭代对象

g = (x * x for x in range(10))
for n in g:
... print(n)

所以,我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现:
斐波拉契数列:

点击查看代码
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'

fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
把上述函数变为generator函数:

点击查看代码
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

用for循环调用generator时,发现拿不到generator的return语句的返回值:

for n in fib(6):
... print(n)
...
1
1
2
3
5
8

想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

g = fib(6)
while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

generator函数和普通函数的执行流程不一样

generator的函数,在每次调用next()的时候执行,遇到yield语句返回再次执行时从上次返回的yield语句处继续执行
e.g

点击查看代码
def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

调用时:

o = odd()
next(o)
step 1
1
next(o)
step 2
3
next(o)
step 3
5
next(o)
Traceback (most recent call last):
File "", line 1, in
StopIteration

在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错。

注意:调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。

next(odd())
step 1
1
next(odd())
step 1
1
next(odd())
step 1
1

上述代码实际创建了3个完全独立的generator,正确写法应先创建一个generator对象,然后对这个对象调用next()

小结:在python中可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator,generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束

标签:...,函数,generator,python,生成器,yield,next,step,理解
From: https://www.cnblogs.com/luwanzi/p/17479668.html

相关文章

  • python 操作文件/文件夹 案例
    importosimportshutilimportglobstr_input=input("输入文件夹名即格式:")str_addr=r"D:\360极速浏览器下载"str_dest=os.path.join(str_addr,str_input)list_glob=list(glob.glob(os.path.join(str_addr,"*."+str_input+"*")))&......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-3-离线搭建playwright环境
    1.简介有些小伙伴或者童鞋们私信留言说自己是在公司局域网办公,或者公司为了安全对网络管控比较严格(尤其是一些大的国企、央企),总之就是一句话无法连到外网去在线下载,宏哥刚看到留言时觉得这问题还留言问啊,你找个有网的电脑下载好安装包然后安装就可以用了。(第一种情况及解决办法:带......
  • python对接事务性MSMQ队列
    研究了很久,逐步了解到原理后,发现python发送消息到事务性msmq肯定可行。现在能搜到的资源没有任何一篇文章说明了这个,包括gpt都一样。废话不多说,直接上代码 importwin32com.client#关键代码必须使用gencache导入"MSMQ.MSMQQueueInfo"win32com.client.gencache.Ensure......
  • 学了Python后还用学R语言吗?
    学习R语言是否有必要取决于你的具体需求和背景。虽然R语言和Python都是数据科学领域广泛使用的编程语言,但它们之间还是存在一些差异。如果你主要从事数据分析、统计建模或者数据可视化等工作,那么学习R语言可能更为适合。R语言在数据处理和统计分析方面具有很强的优势,并内置许多常......
  • Python中的*(星号)和**(双星号)详解 通俗易懂
    Python和C++不同,并没有指针,因此python中的*号作用和C++中不同。网上对于这方面的教程写的啰啰嗦嗦,一点不简明扼要。看的让人找不到重点。我这里快速的讲解一下。1.最简单的不用细说,是一个乘法运算符号a=1b=2c=a*b输出c当然是1×2=2。相信这并非是大家关心的重点。2.收集列表中多......
  • 对python迭代器的理解
    迭代器的接口迭代器的用法自定义迭代器迭代器的意义1迭代器的接口可迭代对象计算对象之间的共同属性得到可迭代对象的共同属性上述对象都是容器类型,都有长度加入文件对象再次求交集得到可迭代对象的唯一共同接口:_iter_生成了迭代器同样方法计算迭代器的共同......
  • Python:packaging包解析语义化版本(Semantic Versioning)
    参考文章语义化版本2.0.0语义化版本与其在Python中的使用packaging是python的pip自带包,不需要额外安装#-*-coding:utf-8-*-"""@File:demo.py@Date:2023-06-09"""frompackagingimportversioncurrent_version='1.3.4'parsed_versio......
  • 深入理解 Istio 流量管理的超时时间设置
    环境准备部署httpbin服务:kubectlapply-fsamples/httpbin/httpbin.yaml部署sleep服务:kubectlapply-fsamples/sleep/sleep.yamlhttpbin服务作为接收请求的服务端,sleep服务作为发送请求的客户端。设置超时时间在sleep服务中向httpbin服务发出请求:export......
  • python基础
    第1课初识Python程序设计语言_哔哩哔哩_bilibili主流语言介绍:编译器与解释器:python特点:......
  • 【python】关键字global
    关键字global1.局部变量和全局变量重名:定义了一个全局变量site,接着,我们定义了一个函数func,同时,在函数func里面,我们首先打印变量site的值,接着再次给变量site赋值。最后,调用函数func,此时程序报错,理论上我们在func函数里面第一次打印使用的应该是全局变量site,但实际上程......