python - Eratosthenes 筛法中的生成器递归跳过步骤

标签 python recursion generator sieve-of-eratosthenes generator-expression

我在此处编写的筛选算法遇到了问题。我现在已经尝试修复它总共大约 10 个小时。我在这里四处寻找类似的问题,但我似乎找不到遇到过这个问题的人。我是 python 的新手,在阅读了大量生成器文档后,我设法编写了有效的代码。但是,我仍然不知道为什么我的第一次尝试失败了。

我所想到的是,在每个连续的筛选步骤中,gen1 似乎实际上并没有被清空。因此,我尝试交替使用名称 gen1 和 gen2,删除每个名称以避免此问题。那也没用。

我真的很感激对此有一些见解,以及任何改进我现在所拥有的东西的建议。

这是失败的代码:

def primes(n):
    "yields primes up to n. For use with large n"
    q = 0
    yield 2
    gen1 = (x for x in range(3,n,2))
    while q*q < n:
        q = next(gen1)
        gen1 = (x for x in gen1 if x%q != 0)
        yield q
    else:
        while 1:
            try:
                yield next(gen1)
            except:
                StopIteration
                break

这是我当前的代码:

import math
global gen1
global gen
def gen1(x):
    for i in range(3,x,2):
        yield i
def gen(generator,n):
    "Input generator and current starting 'index' for the generator"
    # Recursively defines new generator for sieve of Eratosthenes
    for i in range(n+1):
        predicate = next(generator)
        yield predicate
    for i in generator:
        if i % predicate != 0:
            yield i
def primes(n):
    yield 2
    a = gen1(n)
    for i in range(math.ceil(math.sqrt(n))):
        a = gen(a,i)
    yield from a

最佳答案

基本问题之一是范围。在这一行中:

  gen1 = (x for x in gen1 if x%q != 0)

q 的值使用的是不是q在生成器表达式被创建 时被绑定(bind),而是 q 的(不断变化的!)值在生成器表达式执行的时候。这与在任何类型的嵌套函数中引用非局部变量的方式相同。

要在创建时捕获绑定(bind),显而易见且简单的方法是改为编写一个函数,并传递您希望它使用的值。例如,这个重写在这方面和其他几个方面更像 Pythonic:

def primes(n):
    "yields primes up to n. For use with large n"

    def gen(gen1, q):
        for x in gen1:
            if x % q:
                yield x

    q = 0
    yield 2
    gen1 = iter(range(3, n, 2))
    while q*q < n:
        q = next(gen1)
        gen1 = gen(gen1, q)
        yield q
    yield from gen1

现在 gen() 正文中使用的值正是那些传递给它的,所以它是显而易见的而不是一个谜;-)

关于python - Eratosthenes 筛法中的生成器递归跳过步骤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53807182/

相关文章:

python - 有没有办法清理jinja2产生的html?

python - 如何摆脱 django 中的密码限制(例如密码必须为 8 个字符,密码不能与用户名太相似等)

sql - 如何在递归SQL查询中找到子树中的所有节点?

javascript - TypeScript async/await 与 JS tj/co

python - 使用 boto3 从 S3 存储桶中读取多个 csv 文件

python - 在字符串列表中搜索部分字符串

c - 从树的每个节点添加整数

c++ - 斐波那契数列

python - 为什么这段代码不打印 3

javascript - 如何延迟 JavaScript 生成器函数中的循环?