函数中的“yield”语句是什么?

时间:2012-08-22 08:07:37

标签: python

  

可能重复:
  The Python yield keyword explained

有人可以向我解释一下yield语句在这段代码中实际做了什么:

 def fibonacci():
     a, b = 0, 1
     while True:
         yield a
         a, b = b, a+b

表示fibonacci()中的数字:#将生成器用作迭代器;打印号码

到目前为止我所理解的是,我们正在定义一个没有参数的函数finonacci()? 我们定义ab的函数内部等于0和1,接下来,虽然这是真的,但我们正在屈服a。这到底是做什么的?而且,在屈服a的同时? a现在等于b,而b现在等于a + b

下一个问题,对于fibonacci()中的数字,这对于函数中的每个数字还是什么意味着什么?我同样难以理解产量和“数量”实际上在做什么。显然我知道它对fibonacci()打印数字中的每个数字都有意义。我是否真的在不知情的情况下定义数字?

谢谢,对不起,如果我不清楚的话。顺便说一句,这是项目欧拉,如果我知道如何编程这将是一件轻而易举的事情,但我正在努力学习这一点。

4 个答案:

答案 0 :(得分:11)

使用yield使该函数成为生成器。 生成器将继续在每个循环上产生a变量,等待调用生成器的next()方法继续进行下一个循环迭代。

或者,在您returnStopIteration被提升之前。

略微修改以显示StopIteration的使用:

>>> def fib():
...     a = 0
...     b = 1
...     while True:
...         yield a
...         a = b
...         b += a
...         if a > 100:
...             raise StopIteration
...
>>>
>>> for value in fib():
...     print value
...
0
1
2
4
8
16
32
64
>>>

>>> # assign the resulting object to 'generator'
>>> generator = fib()
>>> generator.next()
0
>>> generator.next()
1
>>> for value in generator:
...     print value
...
2
4
8
16
32
64
>>>

答案 1 :(得分:4)

当代码调用fibonacci时,会创建一个特殊的生成器对象。请注意,没有代码被执行 - 只返回一个生成器对象。当您稍后调用其next方法时,该函数将执行,直到遇到yield语句。提供给yield的对象将被返回。当您再次调用next方法时,该函数会再次执行,直到遇到yield为止。如果没有yield语句并且到达函数结尾,则会引发StopIteration异常。

请注意,函数内的对象在next的调用之间保留。这意味着,当代码在下一个循环中继续执行时,调用yield的范围内的所有对象的值都会从之前的next调用返回的位置开始。

关于生成器的一个很酷的事情是它们允许使用for循环进行方便的迭代。 for循环从fibonacci调用的结果中获取生成器,然后使用next生成器对象的方法执行循环检索元素,直到遇到StopIteration异常。

答案 2 :(得分:4)

生成器具有可迭代的特殊属性,它们不会为其值消耗内存。

他们通过计算新值来实现这一点,当迭代时需要它。

即。

def f():
    a = 2
    yield a
    a += 1

for ele in f():
    print ele

会打印

 2

所以你使用一个函数作为一个可以保持返回值的迭代。 当您需要大量内存使用时,这尤其有用,因此您无法负担列表推导的使用

li = [ele*10 for ele in range(10)]

将整个内存空间作为列表

但如果您只想迭代它,则不能单独访问

使用

来提高内存效率
def f():
    i=0
    while i<10
        yield i*10
        i += 1

将使用1个内存空间,因为我一直在重复使用

这是一个捷径

ge = (i*10 for i in range(10))

您可以执行以下任何操作

for ele in f():

for ele in li:

for ele in ge:

获得相同的结果

答案 3 :(得分:1)

这个answer是对yield语句以及迭代器和生成器的一个很好的解释。

具体来说,第一次调用fibonaci()会将a初始化为0,将b初始化为1,输入while循环并返回a。 任何下一个电话会在yield语句后开始,影响baa+bb,然后转至{{1}的下一次迭代1}}语句,再次访问while语句,然后再次返回yield