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,因为它应该......
任何帮助将不胜感激!
答案 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)))