求和数字


78

如果我想找到一个数字的总和,即:

  • 输入: 932
  • 输出:14,即(9 + 3 + 2)

最快的方法是什么?

我本能地做到了:

sum(int(digit) for digit in str(number))

我在网上找到了这个:

sum(map(int, str(number)))

哪种方法最适合提高速度,还有其他方法甚至更快吗?


3
这些很好并且相当。map快一点。
Pavel Anossov

您可以做x % 9,看看这篇文章:sjsu.edu/faculty/watkins/Digitsum0.htm
Washington Guedes

Answers:


113

您发布的两行都很好,但是您可以纯粹以整数来完成,这将是最有效的:

def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

或搭配divmod

def sum_digits2(n):
    s = 0
    while n:
        n, remainder = divmod(n, 10)
        s += remainder
    return s

没有增加分配的版本甚至更快:

def sum_digits3(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

> %timeit sum_digits(n)
1000000 loops, best of 3: 574 ns per loop

> %timeit sum_digits2(n)
1000000 loops, best of 3: 716 ns per loop

> %timeit sum_digits3(n)
1000000 loops, best of 3: 479 ns per loop

> %timeit sum(map(int, str(n)))
1000000 loops, best of 3: 1.42 us per loop

> %timeit sum([int(digit) for digit in str(n)])
100000 loops, best of 3: 1.52 us per loop

> %timeit sum(int(digit) for digit in str(n))
100000 loops, best of 3: 2.04 us per loop

3
sum_digits3()应该使用//代替/,对吧?否则我会得到错误的答案。
LarsH 2014年

我是否需要在“ while n:”上进行解释?我不知道Python如何理解何时停止。例如,数字总和324应该为3 + 2 + 4。对于最后一个(前三位数字),在while循环中,3/10 = 0,然后变为“ while 0:”。那么,虽然0对循环意味着False,然后退出循环并返回s呢?
2014年

3
是的,在需要布尔值的地方,有些事情等同于False。参见此处:docs.python.org/2/library/stdtypes.html#truth-value-testing
Pavel Anossov 2014年

1
是否可以通过公式找到整数的奇数序列的数字总和?
Anoop Toffy

4
n您的%timeit通话的价值是什么?
d8aninja

15

如果要一直对数字求和,直到得到一个数字(我最喜欢的数字可被9整除的特征之一),则可以执行以下操作:

def digital_root(n):
    x = sum(int(digit) for digit in str(n))
    if x < 10:
        return x
    else:
        return digital_root(x)

事实证明,它本身的速度非常快...

%timeit digital_root(12312658419614961365)

10000 loops, best of 3: 22.6 µs per loop

1
巧妙地将功能折叠起来!
vashts85 '16

递归!@ vashts85
d8aninja '16

我也是,被9整除的是什么?
罗纳尔多·纳西门托

@RonaldoNascimento我不知道,但是让我着迷。和3s。
d8aninja

1
对于数字根(基数为10的数字),存在一个直接公式:digital_root(n) = n-9*(n-1//9)
reschu

7

这可能有帮助

def digit_sum(n):
    num_str = str(n)
    sum = 0
    for i in range(0, len(num_str)):
        sum += int(num_str[i])
    return sum

1
谢谢,这个帮助我解决了这个问题:在对数字进行求和后,检查给定的数字是否可以取模0。
Yannis Dran,2016年

4

在完成一些Codecademy挑战后,我解决了以下问题:

def digit_sum(n):
arr = []
nstr = str(n)
for x in nstr:
    arr.append(int(x))
return sum(arr)

2

在解决问题的挑战网站之一上发现了这一点。不是我的,但是可以。

num = 0            # replace 0 with whatever number you want to sum up
print(sum([int(k) for k in str(num)]))


1

最好的方法是使用数学。
我从学校就知道这一点。

def digital_sum(num):
    return (num % 9) or num and 9

只是不知道它在代码中如何工作,但我知道它是数学

如果一个数字可被9整除,那么digital_sum将为9,
如果不是这种情况,num % 9则将为数字和。


请参阅此评论中的链接以获取解释。
snakecharmerb

0
def digitsum(n):
    result = 0
    for i in range(len(str(n))):
        result = result + int(str(n)[i:i+1])
    return(result)

“结果”初始化为0。

在for循环中,数字(n)转换为字符串,然后用循环索引(i)分割并获取每个数字。---> str(n)[ i:i + 1 ]

此切位数字转换回整数----> int(str(n)[i:i + 1])

因此增加了结果。


2
请添加几句话来解释您的代码以及它如何解决该问题。
Yannis

0
def sumOfDigits():

    n=int(input("enter digit:")) 
    sum=0
    while n!=0 :

        m=n%10
        n=n/10
        sum=int(sum+m)

    print(sum)

sumOfDigits()

5
你好!欢迎光临本站!尽管您的答案似乎是解决该问题的有效方法,但它并没有解决问题本身:“哪个更快?” 鉴于这是速度问题,您能否显示解决方案与给出的示例的测试结果?
Kind Stranger

0

您也可以使用名为divmod()的Built_in_function尝试此操作;

number = int(input('enter any integer: = '))
sum = 0
while number!=0: 
    take = divmod(number, 10) 
    dig = take[1] 
    sum += dig 
    number = take[0] 
print(sum) 

您可以输入任意数字


0
reduce(op.add,map(int,list(str(number))))

测试:

from datetime import datetime
number=49263985629356279356927356923569976549123548126856926293658923658923658923658972365297865987236523786598236592386592386589236592365293865923876592385623987659238756239875692387659238756239875692856239856238563286598237592875498259826592356923659283756982375692835692385653418923564912354687123548712354827354827354823548723548235482735482354827354823548235482354823548235482735482735482735482354823548235489235648293548235492185348235481235482354823548235482354823548235482354823548234



startTime = datetime.now()

for _ in  range(0,100000) :
    out=reduce(op.add,map(int,list(str(number))))

now=datetime.now()
runningTime=(now - startTime)

print ("Running time:%s" % runningTime)
print(out)

上映时间:0:00:13.122560 2462



0

我提出了一个递归解决方案:

def sumDigits(num):
#   print "evaluating:", num
  if num < 10:
    return num

  # solution 1
#   res = num/10
#   rem = num%10
#   print "res:", res, "rem:", rem
#   return sumDigits(res+rem)

    # solution 2
  arr = [int(i) for i in str(num)]
  return sumDigits(sum(arr))

# print(sumDigits(1))
# print(sumDigits(49))
print(sumDigits(439230))
# print(sumDigits(439237))

0

以10为底的数字可以表示为一系列形式

a×10 ^ p + b×10 ^ p-1 .. z×10 ^ 0

因此,数字的总和就是项的系数的总和。

根据此信息,数字总和可以像这样计算:

import math

def add_digits(n):
    # Assume n >= 0, else we should take abs(n)
    if 0 <= n < 10:
        return n
    r = 0
    ndigits = int(math.log10(n))
    for p in range(ndigits, -1, -1):
        d, n = divmod(n, 10 ** p)
        r += d
    return r

这实际上是在接受的答案中连续除以10的结果。鉴于此函数与公认的答案相比需要进行额外的计算,因此发现此方法的性能较差并不奇怪:它慢了大约3.5倍,慢了大约两倍。

sum(int(x) for x in str(n))

-1
num = 123
dig = 0
sum = 0
while(num > 0):
  dig = int(num%10)
  sum = sum+dig
  num = num/10

print(sum)//确保在此行上方添加空间


num不小于0。什么都不会发生。使之大于,这可以起作用。
sorak

是的..错误地小于。现在,它大于和工作正常
贾扬特·潘迪

-1

你可以试试这个

def sumDigits(number):
    sum = 0
    while(number>0):
        lastdigit = number%10
        sum += lastdigit
        number = number//10

    return sum

-2

它仅适用于三位数,但适用

a = int(input())
print(a // 100 + a // 10 % 10 + a % 10)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.