【问题标题】:How to add numbers in a range如何在一个范围内添加数字
【发布时间】:2017-08-18 21:11:19
【问题描述】:

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

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

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

【问题讨论】:

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

标签: python list project add


【解决方案1】:

您的问题是您在循环的每次迭代中都没有保留任何价值。您的循环将通过以下方式修复:

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() 将通过避免 list 构造 range() 来进行优化。

但是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 建议的方法。

【讨论】:

  • @ChristianDean,我感谢为改进答案所做的努力,但是,我选择回滚编辑。虽然很明显 OP 正在使用 Py2.X,但该问题并未明确标记为 Py2 和 range() 在 Py2 和 Py3 中都有效。我会记下在 Py2 中使用xrange()
  • 很公平。只是想你可能想使用xrange,因为 OP 使用了它,而xrange 更像 Python3 的range
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

    • 第一个将遍历范围并创建一个仅可被35 整除的值的列表,然后遍历该列表以求和。第二个将遍历生成器,该生成器遍历生成可被35 整除的值。从速度的角度来看,这两种方法之间的差异可以忽略不计,从空间的角度来看,发电机获胜。
    【解决方案4】:
    sum(set(range(0, 1000, 3) + range(0, 1000, 5)))
    

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

    【讨论】:

      【解决方案5】:

      试试这个:

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

      【讨论】:

        【解决方案6】:

        一个班轮:

        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) 
        

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

        【讨论】:

          猜你喜欢
          • 2021-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-06
          • 1970-01-01
          • 2023-01-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多