我在n1
中有一个很大的列表,其中有数字listn1
。如果被乘数不在另一个列表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)
问题是:这种方法是徒劳的。计算
listn1
和listn2
需要几秒钟,因此我知道要添加的数字超过一百万。但是我昨天晚上开始了求和,今天早晨仍然在运行。有没有Python的方法可以加快这种求和速度?
最佳答案
我有2条建议给您。
首先,您不必在每次迭代中都将i
与n1
相乘。您可以更换
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
。举一个简单的例子,看看this。要处理
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))