批量更新Python列表的一部分

时间:2015-08-15 03:30:58

标签: python list slice sieve-of-eratosthenes

我已经编写了一个简单的Eratosthenes Sieve实现,我想知道是否有更有效的方法来执行其中一个步骤。

def eratosthenes(n):
    primes = [2]
    is_prime = [False] + ((n - 1)/2)*[True]
    for i in xrange(len(is_prime)):
        if is_prime[i]:
            p = 2*i + 1
            primes.append(p)
            is_prime[i*p + i::p] = [False]*len(is_prime[i*p + i::p])
    return primes

我正在使用Python的列表切片来更新我的布尔值列表is_prime。每个元素is_prime[i]对应一个奇数2*i + 1

is_prime[i*p + i::p] = [False]*len(is_prime[i*p + i::p])

当我找到素数p时,我可以标记与该素数False的倍数对应的所有元素,并且因为所有小于p**2的倍数也是较小素数的倍数,可以跳过标记那些。 p**2的索引为i*p + i

我担心计算[False]*len(is_prime[i*p + 1::p])的成本,我试图将其与其他两种我无法工作的策略进行比较。

出于某种原因,公式(len(is_prime) - (i*p + i))/p(如果是正数)并不总是等于len(is_prime[i*p + i::p])。是因为我已经计算出错误的切片长度,还是有一些我没有抓到的切片的微妙之处?

当我在我的函数中使用以下行时:

print len(is_prime[i*p + i::p]), ((len(is_prime) - (i*p + i))/p)
is_prime[i*p + i::p] = [False]*((len(is_prime) - (i*p + i))/p)

我得到以下输出(案例n = 50):

>>> eratosthenes2(50)
7 7
3 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in eratosthenes2
ValueError: attempt to assign sequence of size 2 to extended slice of size 3

我还尝试使用以下内容替换批量更新行:

for j in xrange(i*p + i, len(is_prime), p):
    is_prime[j] = False

但是对于n的大值,这会失败,因为xrange不会取任何大于长的值。我放弃了试图将itertools.count与我需要的东西搏斗。

是否有更快更优雅的方法来批量更新列表切片?我有什么办法可以解决我尝试的其他策略,以便我可以将它们与工作策略进行比较吗?谢谢!

0 个答案:

没有答案