【问题标题】:How does generator really work?(Python3.5)生成器如何真正工作?(Python3.5)
【发布时间】:2017-09-30 00:27:48
【问题描述】:

我是 python 新手。我最近了解了生成器和过滤器(我假设它也是一个生成器)。然后我对以下代码感到非常困惑:

>>> def _not_divisible(n):
        return lambda x: x % n > 0

>>> def _odd_iter():
        n = 1
        while True:
                n = n + 2
                yield n

>>> def primes():
        yield 2
        it = _odd_iter()
        while True:
                n = next(it)
                yield n
                it = filter(_not_divisible(n), it)

>>> for n in primes():
        if n < 1000:
                print(n)
        else:
                break

据我了解,代码中实际上有三个生成器(包括过滤器)。 '_odd_iter' 是所有奇数。 'primes' 都是素数。而'filter'是除2以外的素数。

但是在primes()中,'next''it'的第一个元素,然后传递给'_not_divisible' strong>,所以我认为在等式 'it = filter(...)' 左侧 'it' 是一个等于 'n'。 'it' 怎么会再次作为数字传递给 'next()'

>>> next(primes())
2

还有一个问题,无论我使用多少次“下一个”,它总是返回 2 而不是主要流。

非常感谢您帮助我

【问题讨论】:

  • 它总是返回两个,因为primes() 总是一个新的生成器。打p=primes(),然后打几次next(p)
  • 在回答第二个问题之前,您实际上在问什么?
  • filter 不返回单个数字。它接受一个函数和一个可迭代对象作为 args,并返回一个新的可迭代对象,根据函数 arg 产生的值是 True-ish。
  • 当 _not_divisible 与 'n' 一起传递时,过滤器真正返回什么,一个数字而不是一个列表。(对不起,混淆,英语不是我的母语。)
  • 请注意,_not_divisible 是一个函数 factory。当你将它传递给n 时,它会返回一个接受单个 arg (x) 的函数;当 x 不能被您最初传递给 _not_divisiblen 整除时,该函数返回 True。

标签: python python-3.5


【解决方案1】:

我会尽量解释清楚。

primes() 返回一个生成器。当从 it(不是从 primes())屈服时,会发生以下情况:

  1. 它产生一次2
  2. it 被设置为 odd_iter() 返回的生成器,它产生所有以 3 开头的奇数。
  3. 进入了一个无限循环。
  4. 我们从it 获取下一个元素(第一次是3)并生成它。
  5. 现在是棘手的部分:it 被分配了一个过滤器对象,该对象采用以前的 it,并且只允许不能被最后生成的数字整除的数字通过。
  6. 转到 4。

这意味着每当我们得到一个素数时,这个生成器就会多嵌套一层。也许通过查看 it 是什么来最好地说明这一点:

  1. all odd numbers starting with 3
  2. all numbers not divisible by 3 in (all odd numbers starting with 5)
  3. all numbers not divisible by 5 in (all numbers not divisible by 3 in (all odd numbers starting with 7))
  4. all numbers not divisible by 7 in (all numbers not divisible by 5 in (all numbers not divisible by 3 in (all odd numbers starting with 9)))
  5. ...

正如我在评论中所说,next(primes()) 总是返回 2 的原因是每次调用 primes() 都会返回一个新的生成器。你的意思是:

>>> p = primes()
>>> next(p)
2
>>> next(p)
3

【讨论】:

    【解决方案2】:

    此代码中有无限数量的生成器。

    it 始终是生成器。每次通过循环时,都会发出一个素数,it 被其自身的过滤版本替换,该版本消除了该数字的倍数。示例:在发出数字 11 的那一刻,it 是:

    • 一个过滤器消除了 7 的倍数,在
      • 过滤器消除了 5 的倍数,位于
        • 过滤器消除了 3 的倍数,在
          • 奇数的原始生成器。

    ...总共有 5 个活动生成器,包括 primes() 本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-12
      • 2015-02-12
      • 2015-01-07
      • 2019-08-22
      • 2014-03-02
      • 2015-09-15
      • 2013-04-04
      • 2013-01-06
      相关资源
      最近更新 更多