创建生成器的方法
a=[x for x in range(5)]
print(a)
print(type(a))
输出:
[0, 1, 2, 3, 4]
(<generator object <genexpr> at 0x7f6f8f791900>, generator)
下面以
斐波那契数列
来举例
斐波那契数列
指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........
这个数列从第3项开始,每一项都等于前两项之和。
使用迭代器-斐波那契数列
# 使用迭代器-斐波那契数列
# 1,1,2,3,5,8,13...
class FiaInterator(object):
def __init__(self):
self.num1=1
self.num2=1
pass
def __iter__(self):
return self
def __next__(self):
temp=self.num1
self.num1,self.num2=self.num2,self.num1+self.num2
return temp
pass
f=FiaInterator()
print(next(f))
print(next(f))
print(next(f))
print(next(f))
使用生成器生成-斐波那契数列
# 使用生成器生成-斐波那契数列
def FiaGenerator():
num1=1
num2=1
while True:
temp=num2
num1,num2=num2,num1+num2
yield temp
print("yield is done")
f=FiaGenerator()
print(next(f))
print(next(f))
print(next(f))
print(next(f))
yield
关键字只要有yield关键字,那么虽然看上去是调用函数,实际上已经变成了创建一个 生成器对象
通过next调用 生成器,可以让 这个带有yield的def代码块,开始执行
如果是第一次执行,则从def代码块的开始部分执行,直到遇到yield为止,并且把yield关键字后的数值返回,当做next()的返回值
如果不是第一次执行,则从上一次暂停的位置执行(即从上一次yield关键字的下一个语句开始执行),直到遇到下一次yield为止,并且把yield关键字后的数值返回,当做next()的返回值
注意:
要知道一个def代码块,只要有yield就不再是函数,而是生成器
要知道调用def代码块(普通函数)与调用带有yield的def代码块(生成器)的调用方式不同
要注意return与yield的功能也不同
return接收一个函数,且有返回值
yield暂停执行一个函数,且有返回值
面试中也会经常用到,一定要将yield掌握
获取生成器def代码块中return值
# 获取生成器def代码块中return值
def fib_generator():
num1 = 1
num2 = 1
temp_num = num1
num1, num2 = num2, num1+num2
yield temp_num
temp_num = num1
num1, num2 = num2, num1+num2
yield temp_num
temp_num = num1
num1, num2 = num2, num1+num2
yield temp_num
return "已经生成了3个斐波那契数列的值..."
fib = fib_generator()
print(next(fib))
print(next(fib))
print(next(fib))
try:
print(next(fib))
except StopIteration as ret:
print(ret.value)
使用send唤醒
# 使用send唤醒
def generator_foo():
# print("01...")
while True:
# print("02...")
num=yield 202
print("03...",num)
g=generator_foo()
#print(next(g))
print(g.send(None))
print(next(g))
print(g.send(100))
调用generatr时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
[5. 总结]
-
使用了
yield
关键字的函数不再是函数,而是生成器 -
yield
关键字有两点作用:- 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
- 将
yield
关键字后面表达式的值作为返回值返回,此时可以理解为起到了return
的作用
-
可以使用
next()
函数让生成器从断点处继续执行,即唤醒生成器(函数) -
Python3中的生成器可以使用
return
返回最终运行的返回值 -
生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
-
生成器的特点:
- 存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存
2023-04-26
网友评论