【问题标题】:What is the difference between Generator-Function and Generator-ObjectGenerator-Function 和 Generator-Object 有什么区别
【发布时间】:2022-08-11 19:53:03
【问题描述】:

在这段代码中,我们必须使用a = MyGen() 才能使用next(a)
如果我们只使用print (next(MyGen())),输出将始终是第一个产量。

def MyGen():
    n=1 
    print(\'first\')
    yield n 

    n+=1
    print(\'second\')
    yield n

    n+=1
    print(\'last\')
    yield n

a = MyGen()
print(next(a))
print(next(a))

print(next(MyGen()))
print(next(MyGen()))

输出:

first
1
second
2
first
1
first
1

Generator-Function 和 Generator-Object 有什么区别?
以及导致此问题的生成器对象(如 a)中存储的内容是什么?

谢谢。

    标签: python generator


    【解决方案1】:

    这类似于类与实例: MyGen() 有点像一个类,调用它每次都会创建一个新对象,从方法的开头开始。这就是为什么每次调用next(MyGen()) 时都会得到first 的原因——因为它们中的每一个都是一个单独的、未命名的生成器对象。 当您将MyGen() 分配给诸如a 之类的变量时,您会保留对一个特定对象的引用,并且您可以继续在该对象上调用next(a) 以从上一个yield 继续执行到下一个。

    【讨论】:

      【解决方案2】:

      要了解 yield 的作用,您必须了解生成器是什么。在你理解生成器之前,你必须理解迭代。 可迭代对象

      创建列表时,您可以一一阅读其项目。一项一项地读取它的项称为迭代:

      >>> mylist = [1, 2, 3]
      >>> for i in mylist:
      ...    print(i)
      1
      2
      3
      

      mylist 是一个可迭代的。当您使用列表推导时,您会创建一个列表,因此是一个可迭代的:

      >>> mylist = [x*x for x in range(3)]
      >>> for i in mylist:
      ...    print(i)
      0
      1
      4
      

      您可以使用“for...in...”的所有内容都是可迭代的;列表、字符串、文件...

      这些可迭代对象很方便,因为您可以随心所欲地读取它们,但是您将所有值存储在内存中,当您有很多值时,这并不总是您想要的。 发电机

      生成器是迭代器,一种只能迭代一次的可迭代对象。生成器不会将所有值存储在内存中,它们会即时生成值:

      >>> mygenerator = (x*x for x in range(3))
      >>> for i in mygenerator:
      ...    print(i)
      0
      1
      4
      

      除了使用 () 而不是 [] 之外,它是一样的。但是,您不能在 mygenerator 中执行 for i 第二次,因为生成器只能使用一次:它们计算 0,然后忘记它并计算 1,然后一个一个地结束计算 4。 屈服

      yield 是一个与 return 一样使用的关键字,除了该函数将返回一个生成器。

      >>> def createGenerator():
      ...    mylist = range(3)
      ...    for i in mylist:
      ...        yield i*i
      ...
      >>> mygenerator = createGenerator() # create a generator
      >>> print(mygenerator) # mygenerator is an object!
      <generator object createGenerator at 0xb7555c34>
      >>> for i in mygenerator:
      ...     print(i)
      0
      1
      4
      

      这是一个无用的示例,但是当您知道您的函数将返回大量值而您只需要读取一次时,它会很方便。

      要掌握yield,你必须明白,当你调用函数时,你写在函数体中的代码是不会运行的。该函数只返回生成器对象,这有点棘手:-)

      然后,您的代码将从每次停止的地方继续使用生成器。

      现在最困难的部分:

      第一次 for 调用从你的函数创建的生成器对象时,它会从头开始运行你的函数中的代码,直到它达到 yield,然后它会返回循环的第一个值。然后,每个后续调用将运行您在函数中编写的循环的另一次迭代并返回下一个值。这将一直持续到生成器被认为是空的,这发生在函数运行时没有达到产量时。这可能是因为循环已经结束,或者因为您不再满足“if/else”。

      Python 由兴高采烈的针鼹

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-08
        • 2014-03-16
        • 1970-01-01
        • 2014-06-17
        • 2013-04-28
        • 1970-01-01
        • 2016-12-28
        相关资源
        最近更新 更多