2013-03-06 91 views
1

沒有很多python /編程經驗。 我需要測試1到10億之間的每個數字,然後將某些數字附加到列表中。目前我正在嘗試使用範圍(0,Billion),但是我發現在我的機器上使用Python 3.3需要大約80秒的時間。有沒有更高效的方法來做到這一點?用Python計算最多10億的最快方法

for i in range(0, Billion) 
    # if i passes test 
    i.append(samplelist) 
+4

我希望你的意思'samplelist.append(我)'。 – nneonneo 2013-03-06 03:14:05

+0

'我需要測試1到10億之間的每個數字,然後在列表中附加一些數字。',我想你最好檢查一下你的算法,而不是微觀優化。 – Abhijit 2013-03-06 03:16:19

+0

您可能想要考慮將計算與[多處理](http://docs.python.org/3.3/library/multiprocessing.html)並行化。 – unutbu 2013-03-06 03:51:26

回答

0

這應該是快一點,但大部分的時間大概花了調用some_test()

samplelist = [i for i in range(1000000000) if some_test(i)] 
+0

仍然沒有範圍那麼快。用我原來的方法計算到只有一百萬美元花費了大約0.07秒......這花費了大約0.11秒,即時猜測有十億時間會加起來 – francium 2013-03-06 03:31:51

2

通常,如果你需要遍歷了1000000000,有一些更好的辦法。例如,你可以使用一些數學性質,以避免測試每一個數字:

samplelist = [x**2 for x in range(int(1000000000**0.5))] # get all perfect squares up to 1000000000 

Python的不是真的那麼快的數值運算。因此,迭代到10億次,並且在每次迭代中做一些事情都會變得緩慢;還有的沒有辦法解決這個除了嘗試更快的解釋器(如PyPy),或在像C.


更高性能的語言編寫的代碼或者,如果要添加元素的數量龐大的列表,那麼請考慮使用生成器來代替。這將避免創建一個龐大的列表的開銷,同時還對很多東西是有用的:

def gen_numbers(n): 
    for i in range(n): 
     if <i passes test>: 
      yield i 

for i in gen_numbers(1000000000): 
    print(i) 
3

號 想想你的機器時間方面具有的代碼。你的測試和附加功能不能被觸及,所以我們所有的東西都是在範圍內。這是你最基本的循環,就像你可以得到的那樣。您可以編寫一個while循環並編寫另一行來自己增加i,但是我懷疑這實際上會增加執行時間,因爲您正在對python解釋器進行更多調用,然後必須對其進行處理。

退一步講,如果你可以優化您的測試程序...

+0

那麼列表理解肯定比反覆調用附加更有效 – 2013-03-06 03:15:39

+2

@gnibbler:不是太多。嘗試分解列表理解。 – nneonneo 2013-03-06 03:16:08

+0

增加一個計數器至少會給你Python 2.7的內存優勢,但Python 3.3中的'range()'似乎更類似於2.7的'xrange()',這意味着並不是所有的十億值都一次存儲在內存中。 – acattle 2013-03-06 03:35:54