添加int和Python的数字

时间:2012-02-05 18:17:56

标签: python

import sys

def keepsumming(number):
    numberlist = []
    for digit in str(number):
        numberlist.append(int(digit))
    total = reduce(add, numberlist)
    if total > 9:
        keepsumming(total)
    if total <= 9:
        return total

def add(x,y):
    return x+y

keepsumming(sys.argv[1])

我想创建一个函数来添加任意数字的各个数字,并保持求和数字,直到结果只有一位数。 (例如1048576 = 1 + 0 + 4 + 8 + 5 + 7 + 6 = 31 = 3 + 1 = 4)。该功能似乎适用于某些鞋带,但不适用于其他鞋带。例如:

$python csp39.py 29

返回None,但是:

$python csp39.py 30

返回3,因为它应该......

任何帮助将不胜感激!

9 个答案:

答案 0 :(得分:7)

正如其他人所说,问题似乎与部分

有关
if total > 9:
    keepsumming(total)  # you need return here!

为了完整起见,我想向您展示如何更优雅地解决此任务的一些示例(如果您感兴趣的话)。第一个也使用字符串:

while number >= 10:
  number = sum(int(c) for c in str(number))

第二个使用模数,因此根本不需要任何字符串操作(这应该快得多):

while number >= 10:
  total = 0
  while number:
    number, digit = divmod(number, 10)
    total += digit
  number = total

如果你想用数字做不同的事情,你也可以使用迭代器:

def digits(number, base = 10):
  while number:
    yield number % base
    number //= base

number = 12345

# sum digits
print sum(digits(number))
# multiply digits
from operator import mul
print reduce(mul, digits(number), 1)

这最后一个是非常好的和惯用的Python,恕我直言。您可以使用它来实现原始功能:

def keepsumming(number, base = 10):
  if number < base:
    return number
  return keepsumming(sum(digits(number, base)), base)

或迭代地:

def keepsumming(number, base = 10):
  while number >= base:
    number = sum(digits(number, base))

更新:感谢Karl Knechtel暗示这实际上是一个非常微不足道的问题。如果基础数学被正确利用,它可以在一行中解决:

def keepsumming(number, base = 10):
  return 1 + (number - 1) % (b - 1)

答案 1 :(得分:5)

有一个非常简单的解决方案:

while number >= 10:
    number = sum(divmod(number, 10))

答案 2 :(得分:4)

我很确定你需要改变

if total > 9:
        keepsumming(total)

进入

if total > 9:
        return keepsumming(total)

与大多数递归算法一样,您需要通过返回下一个调用来传递结果。

答案 3 :(得分:2)

如何简单地转换为字符串和求和?

res = 1234567
while len(str(res)) > 1 :
    res = sum(int(val) for val in str(res))

return res

这就是我用来做的事情:)

答案 4 :(得分:2)

这是一个干净的尾递归示例,其代码设计易于理解:

def keepsumming(n):
    'Recursively sum digits until a single digit remains:  881 -> 17 -> 8'
    return n if n < 10 else keepsumming(sum(map(int, str(n))))

答案 5 :(得分:1)

你走了:

>>> sumdig = (lambda recurse: (lambda fix: fix(lambda n: sum(int(c) for c in str(n)))) (recurse(lambda f, g: (lambda x: (lambda d, lg: d if d == lg else f(f,g)(d))(g(x),x)))))(lambda f: lambda x: f(f,x))
>>> sumdig(889977)
3

对于此解决方案,您肯定会获得全部(如果不是额外的话)。

答案 6 :(得分:0)

您当前编写的代码需要将keepsumming(total)的递归调用替换为return keepsumming(total); python不会自动返回最后一个计算语句的值。

但是,您应该注意您的代码有冗余。

for digit in str(number):
    numberlist.append(int(digit))
total = reduce(add, numberlist)

应该成为

from operator import add
total = reduce(add, (int(digit) for digit in str(number)))

答案 7 :(得分:0)

无需打井循环或递归的可高尔夫代码版本。

>>> import math
>>> (lambda x: sum(int((x * 10 ** -p) % 10) for p in range(math.ceil(math.log(x, 10)))))(1048576)
31

这也许是我要用的。

def sum_digits(number):
    return sum(
        int(number * (10 ** -place) % 10)
        for place in range(math.ceil(math.log(number, 10)))
    )

如果将其追加到列表而不是对整数值求和,则更容易看到发生的情况。

def show_digits(number):
    magnitude = int(math.log(number, 10))
    forms = []
    for digit_place in range(magnitude + 1):
        form = number * (10 ** -digit_place)  # force to one's place
        forms.append(form)
    return forms
>>> show_digits(1048576)
[1048576, 104857.6, 10485.76, 1048.576, 104.8576, 10.48576, 1.048576]

答案 8 :(得分:-1)

对于带有字符串的keepsumming

def keepsumming(number):
    return number if len(number) < 2 \
        else keepsumming(str(sum(int(c) for c in number)))

对于需要数字的keepsumming

def keepsumming(number):
    return number if number < 10 \
        else keepsumming(sum(int(c) for c in str(number)))