我在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)


问题是:这种方法是徒劳的。计算listn1listn2需要几秒钟,因此我知道要添加的数字超过一百万。但是我昨天晚上开始了求和,今天早晨仍然在运行。

有没有Python的方法可以加快这种求和速度?

最佳答案

我有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。举一个简单的例子,看看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))

09-16 00:07