【发布时间】:2017-09-29 19:56:09
【问题描述】:
我正在尝试以 Python 方式生成素数,即使用生成器。
python 代码或多或少如下
def divisor_in_list(n, d):
""" Returns true if a divisor of n is in d, false otherwise"
def primes():
yield 2
primelist = [2]
i = 3
while True:
while divisor_in_list(i, primelist):
i += 2
primelist.append(i)
yield i
我对 Lisp 很陌生,所以我想知道惯用的等价物是什么。根据我到目前为止的研究,我有以下代码
(defun primes ()
(let* ((p (list 2)) (n 3))
(lambda ()
(loop while (divisor-in-slist n p)
do (incf n 2))
(nconc p (list n))
(+ n 0) ;; Not actually sure how to return N directly :(
)
)
)
但是,这段代码有一个问题,即它输出的第一个值是 3。不幸的是,我无法弄清楚如何优雅地修改它以产生 2 作为第一个值。
我绝对可以将 lambda 中的 if 语句和一个额外的变量结合起来,以检查是否是第一次调用该方法,但这看起来很难看。有什么更好的方法?
【问题讨论】:
-
仅供参考“惰性”关键字 => 一个惰性库:clazy
-
丑陋在旁观者的眼中。我在 Python 解决方案中看到了很多:硬编码的初始产量 2,硬编码的 knowns 到 [2] 的初始化,从 3 迭代,最后是递增 2 的“作弊”。素数不会说“2 然后从 3 开始,每隔一个整数等跳过”。因此,Python 解决方案具有各种特定于我们所知道的素数的技巧。从“一个大于 1 的整数,其仅有的两个整数因子是 1 和它自己”再试一次。那么你只需要一个丑陋的技巧:如果 > 2 则跳过两个。
-
@kennytilton 你很搞笑,你知道吗?
标签: python closures lisp common-lisp generator