您的位置:首页 > 编程语言 > Python开发

Python学习笔记8:yield生成器,迭代器的特殊实现

2019-08-03 18:05 267 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_44776065/article/details/98353998

在Python语言中,函数是重要的组成部分,函数在定义好后,调用时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数的结束(最后一行),可以隐式地看作返回为None。函数有一下几个特点:

  • 函数只有在调用时才会被执行,在调用函数时,程序进入不同的内存,所有的变量都会重新创建
  • 函数执行完毕后,或者对程序有一定的影响,或者返回一个值,然后在调用函数代码的地方继续向下执行
  • 函数完成工作以后,所有的局部变量都会消失,只有再次调用时,才会重新写入内存

对于标准的函数而言,只有一个返回对象,但有时会有这样的需求,需要创建一个能够产生很大序列或者无限序列的函数,如果单纯的建立列表将这些元素 一 一 添加,未免会占用很大的内存。这时,就用到了生成器,那什么是生成器呢?
生成器(generator)就是包含yield语句的函数,它是一个不断产生值的函数,yield具有return的功能,但yield更加强大,yield语句返回一个值,函数的语句暂停在这个位置,下一次执行在暂停处开始执行。其特点是:返回值用 yield 语句
例如:

>>> def generator(n):
for i in range(n):
yield i
>>> for i in generator(10):
print(i, end=" ")
0 1 2 3 4 5 6 7 8 9

生成器的特点是需求一个就返回一个,没有需求则会挂起,其通过next()函数完成需求,例如:

>>> gen = iter(generator(10))
>>> next(gen)
0
>>> next(gen)
1
>>> next(gen)
2
>>> next(gen)
3
>>> for i in gen:       #可见其在上一次代码执行器后继续执行
print(i ,end = " " )
4 5 6 7 8 9
>>> next(gen)
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
next(gen)
StopIteration  #迭代完毕,抛出StopIteration异常

生成器可以写在死循环里,但是由于有yield的存在,并不会造成死循环

def Generate():
a , b = 0 ,1
while True:
a , b = b ,a + b
yield a
while True:
n = eval(input("输入一个产生不小于斐波那契数列的数:\n"))
for each in Generate():
#print(each)
if each > n:
break
#先判断,在打印,才能满足条件
print(each , end = " ")
print()
>>> 输入一个产生不小于斐波那契数列的数:
50000
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368

同样也可以使用for - in 语句要求产生的个数

def Fib(n):
a , b = 0 , 1
for i in range(n):
a , b = b , a + b
yield a
while True:
n = eval(input("输入产生斐波那契数列的个数:\n"))
for i in Fib(n):
print(i)
>>>输入产生斐波那契数列的个数:
16
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987

对于Python的生成器,在其他语言中,最简单的生成器应该被称为协程(coroutines),但在Python语言中,我们称之为生成器。生成器可以总结为一下特点:

  • 生成器的出现使得Python更为简洁
  • 生成器的发明使得Python模仿协同程序的概念得以实现
  • 所谓的协同程序就是可以运行的独立的函数调用,这个特殊的函数可以暂定或者挂起,并在需要的时候从程序离开的地方继续执行
  • generator是用来返回一系列的值的,yield后面的语句是生成器返回的结果
  • yield可以保存生成器的执行状态,以便于下一次的执行
  • 生成器是特殊的迭代器,因此可以使用iter()和next()函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: