我开始学习Python,我遇到过生成器函数,其中有yield语句。我想知道这些函数最擅长解决什么类型的问题。


当前回答

我发现这个解释消除了我的疑虑。因为有一种可能,不知道发电机的人也不知道产量

返回

return语句是销毁所有局部变量并将结果值返回(返回)给调用者的语句。如果同一函数稍后被调用,该函数将获得一组新的变量。

收益率

但是,如果退出函数时局部变量没有被丢弃呢?这意味着我们可以从中断的地方恢复函数。这是引入生成器概念的地方,yield语句从函数停止的地方恢复。

  def generate_integers(N):
    for i in xrange(N):
    yield i

    In [1]: gen = generate_integers(3)
    In [2]: gen
    <generator object at 0x8117f90>
    In [3]: gen.next()
    0
    In [4]: gen.next()
    1
    In [5]: gen.next()

这就是Python中return语句和yield语句的区别。

Yield语句使函数成为生成器函数。

因此生成器是创建迭代器的简单而强大的工具。它们像常规函数一样编写,但它们在想要返回数据时使用yield语句。每次调用next()时,生成器都会从停止的地方恢复(它会记住所有数据值以及最后执行的语句)。

其他回答

一堆东西。任何时候你想要生成一个项目序列,但又不想一次将它们全部“物化”到一个列表中。例如,你可以有一个简单的生成器,返回质数:

def primes():
    primes_found = set()
    primes_found.add(2)
    yield 2
    for i in itertools.count(1):
        candidate = i * 2 + 1
        if not all(candidate % prime for prime in primes_found):
            primes_found.add(candidate)
            yield candidate

然后你可以用它来生成后续质数的乘积:

def prime_products():
    primeiter = primes()
    prev = primeiter.next()
    for prime in primeiter:
        yield prime * prev
        prev = prime

这些都是相当简单的示例,但是您可以看到它对于处理大型(可能是无限的!)数据集是多么有用,而无需预先生成数据集,这只是比较明显的用途之一。

请参阅PEP 255中的“动机”部分。

生成器的一个不太明显的用途是创建可中断函数,它允许您在不使用线程的情况下“同时”执行更新UI或运行多个作业(实际上是交错的)。

也适用于打印到n的质数:

def genprime(n=10):
    for num in range(3, n+1):
        for factor in range(2, num):
            if num%factor == 0:
                break
        else:
            yield(num)

for prime_num in genprime(100):
    print(prime_num)

由于没有提到生成器的send方法,这里有一个例子:

def test():
    for i in xrange(5):
        val = yield
        print(val)

t = test()

# Proceed to 'yield' statement
next(t)

# Send value to yield
t.send(1)
t.send('2')
t.send([3])

它展示了向运行中的生成器发送值的可能性。下面视频中关于生成器的更高级课程(包括解释的yield,并行处理的生成器,逃避递归限制等)

David Beazley在PyCon 2014上谈发电机

我发现这个解释消除了我的疑虑。因为有一种可能,不知道发电机的人也不知道产量

返回

return语句是销毁所有局部变量并将结果值返回(返回)给调用者的语句。如果同一函数稍后被调用,该函数将获得一组新的变量。

收益率

但是,如果退出函数时局部变量没有被丢弃呢?这意味着我们可以从中断的地方恢复函数。这是引入生成器概念的地方,yield语句从函数停止的地方恢复。

  def generate_integers(N):
    for i in xrange(N):
    yield i

    In [1]: gen = generate_integers(3)
    In [2]: gen
    <generator object at 0x8117f90>
    In [3]: gen.next()
    0
    In [4]: gen.next()
    1
    In [5]: gen.next()

这就是Python中return语句和yield语句的区别。

Yield语句使函数成为生成器函数。

因此生成器是创建迭代器的简单而强大的工具。它们像常规函数一样编写,但它们在想要返回数据时使用yield语句。每次调用next()时,生成器都会从停止的地方恢复(它会记住所有数据值以及最后执行的语句)。