在循环内保持过滤器输出

时间:2016-06-18 18:39:39

标签: python algorithm generator

我正在尝试以下方法来生成素数直到给定的限制。我想过使用eratosthenes的筛子。当我使用列表时,我得到了正确的输出,但是当我没有将它作为列表时,输出为false并返回所有数字。有没有办法用递归来做到这一点,因为在python中强加了一个递归限制,还有其他方法可以使用下面的结构。我通过Rosetta代码阅读以检查使用集合的实现以及列表,其中他们将数字设置为非字典的素数。

def prime_till(number):
    seq = range(2, number)
    while True:
        try:
            first = seq.__next__()
        except AttributeError:
            first = seq.__iter__().__next__()
        except StopIteration:
            return None
        yield first
        seq = list(filter(lambda x: x % first != 0, seq))

print(list(prime_till(20)))

输出:

[2, 3, 5, 7, 11, 13, 17, 19]

没有列表:

def prime_till(number):
    seq = range(2, number)
    while True:
        try:
            first = seq.__next__()
        except AttributeError:
            first = seq.__iter__().__next__()
        except StopIteration:
            return None
        yield first
        seq = filter(lambda x: x % first != 0, seq)

print(list(prime_till(20)))

输出:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

1 个答案:

答案 0 :(得分:1)

我不是python专家,但我已经对你的代码进行了一些调试。看来,在读取序列时评估lambda表达式。也就是说,在实际表达式x % first中,first每次都被first当前值替换,而不是您创建时的值def prime_till(number): seq = iter(range(2, number)) while True: try: first = next(seq) print(first) except StopIteration: return None if first == 2: seq = filter(lambda x: x % 2 != 0, seq) elif first == 3: seq = filter(lambda x: x % 3 != 0, seq) elif first == 5: seq = filter(lambda x: x % 5 != 0, seq) else: seq = filter(lambda x: x % first != 0, seq) if first == 5: print(list(seq)) prime_till(20) 。过滤器。

这里有一些奇怪的代码来证明它:

2
3
5
[7, 11, 13, 17, 19]

结果:

from functools import partial

def modnotnull(denom, value):
    return value%denom != 0

def prime_till(number):
    seq = iter(range(2, number))
    while True:
        try:
            first = next(seq)
        except StopIteration:
            return None

        yield first
        seq = filter(partial(modnotnull,first), seq)
        #Or a one-liner:
        #seq = filter(partial(lambda denom,value: value%denom != 0,first), seq)

print(list(prime_till(20)))

以下是关于同一主题的另一个答案:Deferred evaluation in python

现在,至于如何解决这个问题,我真的不知道,但我正在研究它。

<强>加了: 我已经使用@schlamar描述的其他问题构建了一些工作代码。

[2, 3, 5, 7, 11, 13, 17, 19]

输出:

modnotnull

说明:

首先我定义一个first函数,它对给定的值和分母执行所需的检查。然后,每次绘制partial值时,我都会使用functools中的partial(modnotnull,2)函数创建一个新函数。基本上,我是按照我在第一个例子中展示的方式动态创建不同的lambdas。 lambda value: value % 2 != 0变为\bWORD\s*((?:(?!WORD)(?:.|\n))*?)\s*BORDERWORD\b ,依此类推。实际上,这会强制python在创建过滤器时评估我的一个参数。