簡體   English   中英

加速 Python 中的求和

[英]Speeding up summation in Python

我在listn1有一個包含數字n1的大列表。 我想添加每個數字的所有倍數,如果被乘數不在另一個列表listn2 (具有特定特征的素數)並且乘積低於最大值max_n 在大多數情況下,被乘數小於 10,但可以達到 100,000。 到目前為止,我的代碼如下所示:

s = 0
for n1 in listn1:
    s += sum(n1 * i for i in range(1, 1 + max_n // n1) if i not in listn2)

問題:這種方法太慢了。 計算listn1listn2需要幾秒鍾,所以我知道有超過一百萬個數字要添加。 但是我昨天晚上開始求和,今天早上它仍在運行。

有沒有一種 Pythonic 的方法來加速這個求和?

我有2個建議給你。

首先,您沒有在每次迭代時將in1相乘。 你可以更換

s += sum(n1 * i for i in range(1, 1 + max_n // n1) if i not in listn2)

s += n1 * sum(i for i in range(1, 1 + max_n // n1) if i not in listn2)

他們完全一樣。

其次if i not in listn2條件下,你有一個簡單的總結:

sum(i for i in range(1, 1 + max_n // n1)

這與sum([1, 2, 3, 4, 5, 6, 7, 8, ..., (max_n // n1)]) ,並且等於(max_n // n1) * (1 + max_n // n1) / 2 舉個簡單的例子,看看這個

要處理if i not in listn2條件下,如果您的listn2較小,您可以總結listn2而不是listn1

因此,找到的總和listn1核減的項目listn2

def sum_until(l, max):
    return sum([x for x in l if x < max])

listn2 = list(set(listn2))

for n1 in listn1:
    finish = max_n // n1
    s += n1 * (finish * (finish + 1) / 2 - sum_until(listn2, finish)) 

編輯:

我想 NumPy 的總和會更快。 使listn2成為一個 numpy 數組:

import numpy as np

listn2 = np.array(list(set(listn2))) 

並使用這個sum_until函數:

def sum_until(listn2, max):
    l = listn2[np.where(listn2 <= max)]
    return int(np.sum(l))

根據船上的建議,我將代碼重新編寫為

setn2 = set(listn2)
s = 0
for n1 in listn1:
    s += n1 * (max_n * (max_n + 1) // 2 - sum(i for i in range(1, 1 + max_n // n1) if i in setn2))

求和現在只需要幾秒鍾,而不是幾小時。

幾個小時后

遇到我的這個老問題,回想起來,我做了正確的事情。 這個想法在這個線程提到這里使用numpy.sum()而不是良好意圖,但錯了,如圖所示這里 如果您使用 numpy,那很好,但是如果您有 Python 列表,請使用推導式。

暫無
暫無

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

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