python - 在 Python 中创建一个简单的素筛

标签 python

<分区>

我使用 Python 编写了一个简单的素筛(埃拉托色尼的无界筛),但出于某种原因,它无法正常工作。这是筛子:

from itertools import count

def sieve():
    nums = count(2)
    while True:
        n = next(nums)
        nums = filter(lambda k: k%n != 0, nums)
        yield n

不幸的是,这不起作用。相反,它只返回与 count(2) 迭代器相同的值。

为了比较,这个:

nums = count(2)
print(next(nums))
nums = filter(lambda k: k%2 != 0, nums)
print(next(nums))
nums = filter(lambda k: k%2 != 0, nums)
print(next(nums))

将打印:

2
3
5

而筛选功能将打印:

2 3个 4

我认为问题出在 Python 的 lambda 的奇怪行为上,但替换这一行:

nums = filter(lambda k: k%n != 0, nums)

与:

def f(k): return k%n != 0
nums = filter(f, nums)

没有解决问题。

最佳答案

问题是 lambda 总是引用 n最新值,而不是 lambda 已创建。最简单的解决方法是使用关键字参数显式捕获值:

from itertools import count

def sieve():
    nums = count(2)
    while True:
        n = next(nums)
        nums = filter(lambda k, n=n: k%n != 0, nums)
        yield n

这个 Python 陷阱是 well-documentedvarious计算器 answers .公平地说,同样的行为也被其他一些具有词法闭包的语言共享,例如 JavaScriptCommon Lisp .

这可能是你在问题中所说的“Python lambda 的奇怪行为”的意思,尽管这种行为与 lambda 无关,但与闭包在引用可变对象时真正捕获的内容有关变量 — 在 Python、JavaScript 和 Common Lisp 中,它捕获变量的最新值,而在 Scheme 中,它捕获变量在创建闭包时的值。

关于python - 在 Python 中创建一个简单的素筛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28994651/

相关文章:

python - 更新和合并 pandas 数据框中的列

python - 从 3 个列表的 zip 中创建字典

python - 如何使用wxpython在图标(不是位图)上绘制非透明文本?

python - HOG人物检测opencv使用WEBCAM

Python 图像库 : How to combine 4 images into a 2 x 2 grid?

python - seaborn lmplot 中的标记

python - 由字母组成的字母

python - 如何保存文件夹和子文件夹中的音频文件(.wav)的频谱图?

python - 矢量化 numpy 追加循环

python - BeautifulSoup .children 或 .content 标签之间没有空格