代码之家  ›  专栏  ›  技术社区  ›  Vicrobot

对生成器函数使用Next()。

  •  2
  • Vicrobot  · 技术社区  · 7 年前

    我有这个发电机功能:

    >>> def gen():
    ...     for i in range(3):
    ...             yield i*i
    

    现在,当我在gen()上调用next()时,它每次都会给出第一个元素。

    >>> next(gen())
    0
    >>> next(gen())
    0
    

    但当我在for循环中使用它时,它会按预期工作:

    >>> for i in gen():
    ...     print(i)
    ... 
    0
    1
    4
    

    有人能解释这种影响的原因吗?还有我在这里遗漏的概念吗??

    2 回复  |  直到 7 年前
        1
  •  2
  •   Samuel Dion-Girardeau    7 年前

    函数每次调用时都返回一个新的生成器 gen() .

    我认为最简单的理解方法是对比你在做什么:

    >>> next(gen())
    0
    >>> next(gen())
    0
    

    有了这个:

    >>> my_gen = gen()
    >>> next(my_gen)
    0
    >>> next(my_gen)
    1
    >>> next(my_gen)
    4
    >>> next(my_gen)Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    在后一种情况下,我从 相同的 发电机。

        2
  •  3
  •   Mazdak    7 年前

    每次调用函数时,它都返回一个生成器对象。每次你打电话给下一个,你就会得到第一个项目 0 * 0 因为你不是在同一个对象上调用下一个对象(每次调用一个新对象)。但在第二种情况下,您循环访问一个生成器对象,它将继续消耗生成器,直到它碰到 StopIteration .

    为了更好地演示,可以从生成器函数创建两个迭代器对象,并同时循环它们:

    In [17]: g = gen()
    
    In [18]: k = gen()
    
    In [19]: for i, j in zip(g, k):
        ...:     print(i, j)
        ...:     
    0 0
    1 1
    4 4