以下是基于收益率的简单方法, 用来计算Fibonacci系列, 解释如下:
def fib(limit=50):
a, b = 0, 1
for i in range(limit):
yield b
a, b = b, a+b
当你把这个输入你的REPL,然后尝试把它称为, 你会得到一个神秘的结果:
>>> fib()
<generator object fib at 0x7fa38394e3b8>
这是因为向 Python 发出的产出信号 表明您想要创建一个生成器, 即一个根据需求产生价值的物体。
那么,你如何生成这些值?这要么直接通过下一个使用内置函数来实现,要么间接地通过将内置函数输入一个消耗值的构造来实现。
使用下个() 内置函数, 您可以直接引用. extext/ __ extext_ , 迫使生成器产生值 :
>>> g = fib()
>>> next(g)
1
>>> next(g)
1
>>> next(g)
2
>>> next(g)
3
>>> next(g)
5
间接地,如果您为循环提供纤维、列表初始化器、图普特初始化器或其他任何期望产生/产生值的对象,您将“组装”生成器,直到它不再产生(并返回):
results = []
for i in fib(30): # consumes fib
results.append(i)
# can also be accomplished with
results = list(fib(30)) # consumes fib
类似地,图普特首发器:
>>> tuple(fib(5)) # consumes fib
(1, 1, 2, 3, 5)
生成器与功能不同, 因为它很懒。 它通过保持本地状态, 并允许您在需要的时候恢复运行来达到这个目的 。
当你喊叫它的时候,
f = fib()
Python 编译函数, 遇到产出关键字, 只需返回生成对象。 似乎没有什么帮助 。
当您要求它生成第一个值时, 它会直接或间接地执行它发现的所有语句, 直到它遇到一个产量, 然后它会返回您提供的产量和暂停值。 对于一个更能证明这一点的例子, 让我们使用一些打印电话( 如果在 Python 2 上用打印“ text ” 代替 打印“ text ” ):
def yielder(value):
""" This is an infinite generator. Only use next on it """
while 1:
print("I'm going to generate the value for you")
print("Then I'll pause for a while")
yield value
print("Let's go through it again.")
现在,输入REPL:
>>> gen = yielder("Hello, yield!")
您现在有一个生成对象, 正在等待一个命令来生成一个值。 使用下一个对象并查看打印的内容 :
>>> next(gen) # runs until it finds a yield
I'm going to generate the value for you
Then I'll pause for a while
'Hello, yield!'
未引用的结果是打印的内容。 引用的结果是从产出中返回的内容。 现在再次调用 :
>>> next(gen) # continues from yield and runs again
Let's go through it again.
I'm going to generate the value for you
Then I'll pause for a while
'Hello, yield!'
生成器记得它被按产出值暂停, 然后从那里恢复。 下一则消息被打印, 并搜索收益声明以在它上再次暂停( 原因是同时循环 ) 。