簡體   English   中英

循環求和與列表理解求和

[英]looping for a sum versus summing a list comprehension

在我進行的那種計算中,我經常遇到需要對至少一個列表上的某些表達式求和。 假設我想在某些列表L中找到x的x ^ 2之和。

sum([val**2 for val in L])

total = 0
for val in L:
    total+=val**2

如果我要表達一個更復雜的表達式,這種變化會改變嗎? 我並不擔心與創建列表相關的內存問題,但是更簡潔的代碼和更快的運行時間很重要。

我基本上想知道人們是否有可能在列出生成器和總和上進行了概率優化,這將使我獲得更快的代碼-使用C而不是python進行循環。

編輯任何搜索此內容的人,答案就是將其轉換為numpy數組,然后進行計算是最快的。

最簡單,最確定的答案就是對其進行測試:

import timeit
import numpy as np

L = range(1000)
M = np.arange(1000)

def f0():
    sum([val**2 for val in L])

def f1():
    total = 0
    for val in L:
        total+=val**2    

def f2():
    np.sum(M*M)

print timeit.timeit("f0()", setup="from __main__ import f0, f1, f2, L, M", number=100)
print timeit.timeit("f1()", setup="from __main__ import f0, f1, f2, L, M", number=100)
print timeit.timeit("f2()", setup="from __main__ import f0, f1, f2, L, M", number=100)

# 0.015289068222
# 0.00959897041321
# 0.000958919525146

如果使用1M而不是1K,則時間的比率相似(這里我也使用number=10所以我不必等待):

# 1.21456193924
# 1.08847117424
# 0.0474879741669

也就是說,這兩種純Python方法大致相同,使用numpy可使計算速度提高10-20倍。

按照湯姆的回答,我想包括創建np數組的成本,並進行更公平的比較,其中我可能要遍歷2個循環。 所以我在這里將x * y加到兩個列表中。

import timeit
import numpy as np

X = range(10000)
Y = range(10000)
M = np.arange(10000)
N = np.arange(10000)

def f0():
    sum([x*y for x in X for y in Y])

def f1():
    sum(x*y for x in X for y in Y)

def f2():
    total = 0
    for x in X:
        for y in Y:
            total += x*y

def f3():
    np.sum(np.array(X)*np.array(Y))

def f4():
    np.sum(M*N)



print timeit.timeit("f0()", setup="from __main__ import f0, f1, f2, f3, f4, X, Y, M, N", number=10)
print timeit.timeit("f1()", setup="from __main__ import f0, f1, f2, f3, f4, X, Y, M, N", number=10)
print timeit.timeit("f2()", setup="from __main__ import f0, f1, f2, f3, f4, X, Y, M, N", number=10)
print timeit.timeit("f3()", setup="from __main__ import f0, f1, f2, f3, f4, X, Y, M, N", number=10)
print timeit.timeit("f4()", setup="from __main__ import f0, f1, f2, f3, f4, X, Y, M, N", number=10)

#73.9396169186
#68.8783578873
#61.4824860096
#0.00859999656677
#0.000278949737549

因此,答案是列表理解比Python中的循環最慢15%到20%。

如果我們已經將其包含在numpy中,那將比創建numpy數組所需的時間快30倍。 創建numpy數組並以numpy進行處理,在數量級上擊敗了純python,這讓我感到驚訝。 我猜應該沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM