埃拉托色尼筛法问题(Python 语法)

发布于 2024-10-31 04:02:55 字数 1209 浏览 1 评论 0原文

所以我正在阅读关于埃拉托斯特尼筛法的维基百科文章,其中包含一个 Python 实现: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm_complexity_and_implementation

def eratosthenes_sieve(n):
    # Create a candidate list within which non-primes will be
    # marked as None; only candidates below sqrt(n) need be checked. 
    candidates = range(n+1)
    fin = int(n**0.5)

    # Loop over the candidates, marking out each multiple.
    for i in xrange(2, fin+1):
        if not candidates[i]:
            continue

        candidates[2*i::i] = [None] * (n//i - 1)

    # Filter out non-primes and return the list.
    return [i for i in candidates[2:] if i]

它看起来像非常简单和优雅的实现。我见过其他实现,甚至是 Python 中的实现,并且我了解 Sieve 的工作原理。但是这个实现的特定工作方式,我有点困惑。似乎编写该页面的人都非常聪明。

我知道它会迭代列表,找到素数,然后将多个素数标记为非素数。

但是这行代码到底做了什么:

candidates[2*i::i] = [None] * (n//i - 1)

我发现它从 2*i 到末尾切片候选,按 i 迭代,所以这意味着 i 的所有倍数,从 2*i 开始,然后转到 3*i,然后转到 4*i 直到完成列表。

n//i - 1) 是什么意思?为什么不将其设置为 False?

但是 [None] * ( 问题只有一个答案,但我认为这是问这个问题的地方,我肯定会感激一个清晰的解释。

So I was reading the Wikipedia article on the Sieve of Eratosthenes and it included a Python implementation:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm_complexity_and_implementation

def eratosthenes_sieve(n):
    # Create a candidate list within which non-primes will be
    # marked as None; only candidates below sqrt(n) need be checked. 
    candidates = range(n+1)
    fin = int(n**0.5)

    # Loop over the candidates, marking out each multiple.
    for i in xrange(2, fin+1):
        if not candidates[i]:
            continue

        candidates[2*i::i] = [None] * (n//i - 1)

    # Filter out non-primes and return the list.
    return [i for i in candidates[2:] if i]

It looks like a very simple and elegant implementation. I've seen other implementations, even in Python, and I understand how the Sieve works. But the particular way this implementation works, I"m getting a little confused. Seems whoever was writing that page was pretty clever.

I get that its iterating through the list, finding primes, and then marking multiples of primes as non-prime.

But what does this line do exactly:

candidates[2*i::i] = [None] * (n//i - 1)

I've figured out that its slicing candidates from 2*i to the end, iterating by i, so that means all multiples of i, start at 2*i, then go to 3*i, then go to 4*i till you finish the list.

But what does [None] * (n//i - 1) mean? Why not just set it to False?

Thanks. Kind of a specific question with a single answer, but I think this is the place to ask it. I would sure appreciate a clear explanation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愁以何悠 2024-11-07 04:02:55
candidates[2*i::i] = [None] * (n//i - 1)

只是一种简洁的编写方式

for j in range(2 * i, n, i):
    candidates[j] = None

,其工作原理是将一个 None 列表分配给一个 candidates 切片。

candidates[2*i::i] = [None] * (n//i - 1)

is just a terse way of writing

for j in range(2 * i, n, i):
    candidates[j] = None

which works by assigning an list of Nones to a slice of candidates.

眼眸 2024-11-07 04:02:55

L * N 创建并连接 LN(浅)副本,因此 [None] * (n//i - 1 ) 给出 ceil(n / i) 乘以 None 的列表。切片赋值 (L[start:end:step] = new_L) 会用 new_L 的项目覆盖切片接触的列表项目。

你是对的,人们也可以将这些项目设置为 False - 我认为这会更好,代码的作者显然认为 None 会更好地指示“划掉了”。但是 None 也可以工作,因为 bool(None) 是 False.. if i 本质上是 if bool(i)< /代码>。

L * N creates and concatenates N (shallow) copies of L, so [None] * (n//i - 1) gives a list of ceil(n / i) times None. Slice assignment (L[start:end:step] = new_L) overwrites the items of the list the slice touches with the items of new_L.

You are right, one could set the items to False as well - I think this would be preferrable, the author of the code obviously thought None would be a better indicator of "crossed out". But None works as well, as bool(None) is False and .. if i is essentially if bool(i).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文