2017-02-19 114 views
0

我是python的新手。正試圖解決問題,但由於TLE而陷入困境。下面的代碼花費了太多時間,大約10秒。現在,我想知道正常的嵌套循環是如此低效或我做錯了什麼?循環在Python-3中花費太多時間

from datetime import datetime 

arr = [1 for i in range(10000)]; # Originally had large size array of length ~10^4 
l = len(arr); 
ans = 0; 
time1 = datetime.now(); 
# arr = sorted(arr); 
for i in range(l):  
    for j in range(i+1,l):   
     ans+= arr[i]*arr[j]; 
print(datetime.now() - time1);  

輸出到上面的代碼:

0:00:10.595463 

我已經知道蟒蛇是基於解釋和比編譯語言,如C++或Java慢。但這很多!

由於python索引是在O(1)中完成的,所以不需要太多時間。

請幫我理解,如果這是python的正常行爲或任何需要改變的地方。

雖然我可以使用numpy,但想以本地方式使用它。請幫忙。

+0

你有49995000次的迭代,這似乎合法的給我。 –

+0

如果您計算出您正在執行的步驟數:使用99999個循環減少的10000個循環,執行3 * 49995000行代碼需要一些時間並不奇怪。 –

+1

https://repl.it/FpH9/1 - 編輯後的版本將repl.it上的運行時間從11.5秒降至6.5秒,ish。 – TessellatingHeckler

回答

1

有些事情可以改進,儘管Python嵌套循環使用默認解釋器的速度很慢。

對於這樣一個腳本,你可以嘗試Pypy替代的CPython的:)

我的結果運行過程中出現的腳本:

$ python3 script.py 
0:00:07.167943 

$ pypy script.py 
0:00:00.150436 

In this other question你可以找到爲什麼有這麼大的差異的解釋兩者之間的運行時間。

PD:請不要在每個語句

1

提升乘法算出總數的結束使用分號提高了速度顯着:

In [1]: arr = [1 for i in range(10000)] 

In [2]: def calc2(arr): 
    ...:  ans = 0 
    ...:  for j in range(len(arr)): 
    ...:   ans += arr[j] * sum(arr[j+1:]) 
    ...:  return ans 
    ...: 

In [3]: %timeit calc2(arr) 
1 loop, best of 3: 1.02 s per loop 

這大約是10倍比快你發佈的時間。


但是你真的應該使用numpy進行數字運算。

下面我已經做了計算的straightforwad轉換上面numpy

In [1]: import numpy as np 

In [2]: def calc(arr): 
    ...:  ans = np.zeros_like(arr) 
    ...:  for j in range(len(arr)): 
    ...:   ans[j] = arr[j] * np.sum(arr[j+1:]) 
    ...:  return np.sum(ans) 
    ...: 

In [3]: arr = np.random.rand(10000) 

In [4]: %timeit calc(arr) 
1 loop, best of 3: 181 ms per loop