我正在創建一個快速方法來生成範圍內的素數列表(0,limit + 1)。在函數中,我最終從名爲primes的列表中刪除名爲可移動的列表中的所有整數。我正在尋找一種快速和pythonic的方式來刪除整數,知道這兩個列表總是排序。從python中的另一個排序列表中移除排序列表的快速和pythonic /乾淨的方式是什麼?
我可能是錯的,但我相信list.remove(n)迭代列表比較每個元素與n。這意味着下面的代碼在O(n^2)時間運行。
# removable and primes are both sorted lists of integers
for composite in removable:
primes.remove(composite)
基於關我的假設(這可能是錯誤的,請確認這是否是正確的),事實上,這兩個列表總是排序,我認爲下面的代碼運行速度更快,因爲它僅循環在O(n)時間之後在列表中一次。然而,它根本不是pythonic或乾淨的。
i = 0
j = 0
while i < len(primes) and j < len(removable):
if primes[i] == removable[j]:
primes = primes[:i] + primes[i+1:]
j += 1
else:
i += 1
有沒有這樣做的功能或簡單的方法呢?什麼是最快的方法?
備註:我沒有實際計時上述功能或代碼。另外,如果可移動列表在過程中被更改/銷燬,則無關緊要。
任何有興趣的全部功能低於:
import math
# returns a list of primes in range(0, limit+1)
def fastPrimeList(limit):
if limit < 2:
return list()
sqrtLimit = int(math.ceil(math.sqrt(limit)))
primes = [2] + range(3, limit+1, 2)
index = 1
while primes[index] <= sqrtLimit:
removable = list()
index2 = index
while primes[index] * primes[index2] <= limit:
composite = primes[index] * primes[index2]
removable.append(composite)
index2 += 1
for composite in removable:
primes.remove(composite)
index += 1
return primes
到'primes.remove'運行的一個呼叫'O(n)的時間' ,所以你乾淨的第二個解決方案也運行在'O(n^2)'的時間,而不是比第一個更快。通過同時迭代兩個列表(使用循環變量'i'和'j',一次只增加其中一個),可以在'O(n)'時間內完成,類似於第二個解決方案,一個單獨的輸出列表。 – pts 2014-09-23 22:07:26
對不起,我打算改變primes.remove()primes = primes [:i] + primes [i + 1:] – DavidC 2014-09-23 22:11:47
看看[Robert William Hank的解決方案](http://stackoverflow.com/a/3035188/190597)。當確定(大致)該元素的索引不是素數時,他使用布爾列表並將元素設置爲False。 – unutbu 2014-09-23 22:12:18