如何在一个范围内添加数字

How to add numbers in a range

嘿,所以我正在尝试挑战将 1000 以下的 3 或 5 的倍数中的每个数字相加,当我输入以下代码时:

for x in xrange(1000):
if x % 3 == 0 or x % 5 == 0:
    place = list([x])
    sum(place)

它只列出了所有 3 和 5 的倍数的数字,有什么办法可以将它列出的所有数字相加吗?

试试这个:

total=0
for x in xrange(1000):
    if x % 3 == 0 or x % 5 == 0:
        total += x

这也是列表理解的一个很好的案例:

total = sum([x for x in xrange(1000) if x % 3 == 0 or x % 5 == 0])

编辑:在这种情况下它甚至不需要是一个列表(而且我认为效率更高,因为[如果我错了请纠正我]求和a生成器只遍历范围一次,而第一个会遍历原始范围,创建一个范围,然后再次遍历它以获得总和):

total = sum(x for x in xrange(1000) if x % 3 == 0 or x % 5 == 0)

与其测试 0 到 1000 之间的每个数字以查看它是否是 3 或 5 的倍数,然后将它们相加,不如生成一个仅包含 0 到 1000 之间的 3 或 5 的倍数的 set

nums = set(range(3, 1000, 3))
nums.update(range(5, 1000, 5))
total = sum(nums)

首先不生成您不想要的数字会更有效率。

(A set 是必需的,因为有些数字是 3 和 5 的倍数,并且该集合将自动仅包含这些数字一次。另请注意,我们的范围完全省略了 0,因为它不影响总和。效率稍微高一点。)

sum(set(range(0, 1000, 3) + range(0, 1000, 5)))

创建范围内数字的列表,按可整除的数字步进,然后删除重复项,对结果求和。

你的问题是你没有在循环的每次迭代中保留任何值。您的循环将固定为:

place = []
for x in range(1000):
    if x % 3 == 0 or x % 5 == 0:
        place.append(x)
sum(place)

或者只是顺便算了一下:

result = 0
for x in range(1000):
    if x % 3 == 0 or x % 5 == 0:
        result += x
result

正如所指出的,一个简单的生成器表达式可以解决问题:

sum(x for x in range(1000) if x % 3 == 0 or x % 5 == 0)

注意:我使用 Py3 - 在 Py2 中 xrange() 将通过避免 range().

list 构造来优化

但是sum(range(n+1))有一个封闭形式:

s(n) = n * (n + 1) // 2

例如:

sum([0, 1, 2, 3, ..., 999]) == 999 * 1000 // 2 == 499500

可以扩展为 sum(range(0, n+1, c)) 为:

s(n, c) = c * (n//c) * (n//c + 1) // 2

例如:

sum([0, 3, 6, 9, ..., 999]) == 3 * (999//3) * (999//3 + 1) // 2 == 166833

所以你可以将问题重写为 s(999, 3) + s(999, 5) - s(999, 15),你必须减去 s(999, 15) 或者你重复计算所有可以被 35 整除的值,例如:

In []:
n = 1000
s = lambda n, c: c  * (n//c) * (n//c + 1) // 2
s(n-1, 3) + s(n-1, 5) - s(n-1, 15)

Out[]:
233168

这是 O(1) 对比 O(n) 提出的所有各种 sum 方法。

一个班轮:

sum((x for x in range(1000) if any((x % 3 == 0, x % 5 == 0))

# less brackets
sum((x for x in range(1000) if x % 3 == 0 or x % 5 == 0) 

使用生成器可确保低内存使用率,即使范围在千万亿之内。