在Wikipedia這是給定一個算法來生成素數:爲什麼這個算法更糟?
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 = [i for i in range(n + 1)]
fin = int(n ** 0.5)
# Loop over the candidates, marking out each multiple.
for i in range(2, fin + 1):
if not candidates[i]:
continue
candidates[i + i::i] = [None] * (n // i - 1)
# Filter out non-primes and return the list.
return [i for i in candidates[2:] if i]
我改變了算法略有下降。
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 = [i for i in range(n + 1)]
fin = int(n ** 0.5)
# Loop over the candidates, marking out each multiple.
candidates[4::2] = [None] * (n // 2 - 1)
for i in range(3, fin + 1, 2):
if not candidates[i]:
continue
candidates[i + i::i] = [None] * (n // i - 1)
# Filter out non-primes and return the list.
return [i for i in candidates[2:] if i]
我首先標出了2的所有倍數,然後我只考慮奇數。當我計算兩種算法(嘗試40.000.000)時,第一個算法總是更好(儘管非常輕微)。我不明白爲什麼。有人可以解釋一下嗎?
P.S .:當我嘗試100.000.000時,我的電腦死機。這是爲什麼?我有Core Duo E8500,4GB內存,Windows 7 Pro 64位。
更新1:這是Python 3的
更新2:這是我的計時:
start = time.time()
a = eratosthenes_sieve(40000000)
end = time.time()
print(end - start)
UPDATE:在寶貴的意見(特別是nightcracker和溫斯頓·尤爾特)我設法代碼我首先打算:
def eratosthenes_sieve(n):
# Create a candidate list within which non-primes will be
# marked as None; only c below sqrt(n) need be checked.
c = [i for i in range(3, n + 1, 2)]
fin = int(n ** 0.5) // 2
# Loop over the c, marking out each multiple.
for i in range(fin):
if not c[i]:
continue
c[c[i] + i::c[i]] = [None] * ((n // c[i]) - (n // (2 * c[i])) - 1)
# Filter out non-primes and return the list.
return [2] + [i for i in c if i]
該算法改進了原來的算法(在頂部提到)由(通常)50%。 (當然,比自動提到的算法更糟糕)。
對Python大師的一個問題:是否有更多的Pythonic方法來以更「功能性」的方式表達最後一個代碼?
更新2:我仍然無法解碼由nightcracker提到的算法。我想我太傻了。
這是'函數式編程'嗎? – Javier 2011-03-24 22:20:34
你可以使用'xrange'而不是'range'來更快地使用for循環 – GWW 2011-03-24 22:27:07
我找到了相反的結果,你最近怎麼做? – 2011-03-24 22:34:03