首页 > 编程语言 >Python 生成器

Python 生成器

时间:2022-11-01 11:55:44浏览次数:47  
标签:Python after 生成器 yield next send print

什么是生成器:

  • 生成器是 Python 中的一个对象(按照某种规律,来生成元素的对象),生成器不是列表,保存了产生元素的算法,同时会记录游标的位置(现在拿到第几个元素了),为了下次继续拿数据,而不是从头开始拿数据。可以通过一直调用 next() 方法获取值,这个对象不保存数据,每次调用会返回一个值,即做到了列表的好处,又不占用空间。
  • 在 Python 中,这种一边循环一边计算的机制,称为生成器:generator,生成器是在需要用到数据的时候再提供,相比列表生成器一次性生成多个数据,不占内存
  • 生成器是一个特殊的程序,可以被用作控制循环的迭代行为,Python 中生成器是迭代器的一种,使用 yield 返回值函数,每次调用 yield 会暂停,而可以使用 next() 函数和 send() 函数恢复生成器。

生成器的创建方式:

  • 生成器表达式
    • a = (expression for iterm in iterable)
  • 生成器函数
    • 在一个普通函数中使用 yield 关键字 
      • yield 类似于 return 函数,可以将 yield 后面的对象返回,并且记住这个返回的位置,下次通过 next 迭代时,代码从 yield 的下一条语句开始执行。
  • 生成器函数内部,不允许使用 return 语句返回任何值,因为生成器函数已经默认返回一个生成器了,但是你可以只写一个 return,后面不带任何值

生成器的取值方式:

  • 通过 next() 函数取值
  • 通过 send(value) 函数取值
    • 通过 next 和 send 函数取值时,当时取完了,会报 StopIteration 停止迭代错误
    • 第一次 send 前如果没有使用 next 函数进入生成器,则第一个 send 只能传入参数 None,send 类似于 next 可以进入生成器中去执行代码,但是 send 需要传入参数,且将传入的参数赋值给代码中的 yield 前的变量
  • 通过 for 循环取值
    • 因为生成器本身就是一个特殊的迭代器

 实例如下,定义生成器及通过 next 和 for 循环执行取值:

# 第一种创建生成器的方式
b = (i for i in range(5))
print(b)    # <generator object <genexpr> at 0x0000000000F5B360>  generator 是一个生成器

# print(b.__next__()) # 通过私有方法 __next__() 进入生成器中取值
# print(next(b))  # 通过内置函数 next() 进入生成器中取值,依次取值,取完后再取就报迭代结束错误

for x in b: # 通过 for 循环取值,生成器本身是一个迭代器,是一个可迭代对象
    print(x)
# 第二种创建生成器的方式 通过yield创建
def func():
    print("hello1")
    yield 1     # yield 类似return,具有返回值作用
    print("hello2")
    yield 2

f = func()
print(next(f)) # 第一次next执行到yield1  结果:hello1和1
print(next(f)) # 第二次next从yield1开始执行,执行到yield2停止    结果:hello2和2

# 结果如下:
hello1
1
hello2
2
# 斐波那契数列 0 1 1 2 3 5 8
def fibo(max):
    n, before, after = 0, 0, 1
    while n < max:
        print(after)
        before, after = after, before+after
        n += 1

fibo(3)

# 通过生成器计算斐波那契数列
def fibo(max):
    n, before, after = 0, 0, 1
    while n < max:
        yield after
        before, after = after, before+after
        n += 1
f = fibo(3)
for i in f:
    print(i)

# 结果如下
1
1
2

 实例如下,定义生成器及通过 send 执行取值:

# send()函数
def func():
    print("hello1")
    count1 = yield 1
    print(count1)
    print("hello2")
    count2 = yield 2
    print(count2)
    yield 3

f = func()
# print(f.next())
#      ||   上下两行代码相等
print(f.send(None))  # 第一次send()前如果没有next(),只能传入一个None,send类似与next可以进入生成器中去执行代码,但是send需要传入参数,且传给代码中yeild前的变量count1
print("--------------")
print(f.send("world1"))
print("--------------")
print(f.send("world2"))

# 结果如下
hello1
1
--------------
world1
hello2
2
--------------
world2
3

 

标签:Python,after,生成器,yield,next,send,print
From: https://www.cnblogs.com/ZhengYing0813/p/16847219.html

相关文章

  • 【Python】AES.MODE_CBC和 AES.MODE_ECB 加解密
    AES加解密MODE_CBC和MODE_ECB两种模式的完整实现 importjsonfromCrypto.CipherimportAESimportbase64importbinascii#数据类classMData():def__i......
  • Python 基础:入门必备知识
    Python基础:入门必备知识1标识符标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。以下......
  • 【Python】django
    安装虚拟环境windowsmkvirtualenv-pC:\Users\Administrator\AppData\Local\Programs\Python\Python38\Python.exedjango_testlinuxmkvirtualenv-ppython3django......
  • python绘制时序图
    使用python绘制时序图《应用时间序列分析》,第6版,王燕,中国人名大学出版社第8章多元时间序列分析,P298,例8-4的数据对1962-1979年美国白领阶层平均年薪和可能对它有显著影......
  • Python代码上传要求
    Python代码上传要求基本要求i==1(√)i==1(X)i==1(X)i==1(√)i<=1(√)i<=1(X)i<=1(X)i<=1(√)函数要求input("内容")(√)......
  • Python学习笔记
    20221031:对比python的列表数组与numpy插件在数据处理效率上的差别,importtime导入了常用的模板,importnumpyasnp导入numpy模块,别名为np。当时在操作时,pycharm没有安装num......
  • 学习python第二天
    ##字符串的操作##tyep查看对象的类型#name="wode"#print(type(name))###常用的类型:strintfloatbool##布尔型:bool##Ture1##flse0#print()#字符串......
  • python3-venv虚拟环境使用-解决包管理|版本控制混乱的问题
    安装sudoaptinstallpython3-venv创建虚拟环境python3-mvenvtest_env会自动在用户目录创建一个test_env的虚拟环境目录开启&使用虚拟环境source~/test_env/......
  • python基础-函数
    1.函数定义  函数就是将完成一件事情的步骤封装在一起并得到最终的结果;  函数名代表了这个函数要做的事情;  函数体是实现函数功能的流程;  添加一个函数也被叫......
  • Python实现限制主机登录
    importparamikoimportdatetimeimporttimef=open('./hostnames.txt','r')#准备主机文件,一台主机占一行hostnames=f.readlines()forhostnameinhostnames:......