如何在python中重复找到每个T数字的数字总和的数字总和,直到它成为一个数字?
Posted
技术标签:
【中文标题】如何在python中重复找到每个T数字的数字总和的数字总和,直到它成为一个数字?【英文标题】:how to find the sum of digits of sum of digits of each of T numbers repeatedly in python till it gets to being a single digit number? 【发布时间】:2019-02-01 03:24:39 【问题描述】:这是我编写的代码,用于从重复次数的数字中获取数字总和,直到总和低于 10:
T = int(input())
for i in range(T):
N = int(input())
def P():
M = [int(d) for d in str(N)]
N = sum(M)
if N<10:
print(N)
else :
return P()
P()
在运行此代码时,它会给我一个错误,例如:
Traceback (most recent call last):
File"C:/Users/AdityaShrivastava/AppData/Roaming/Python/Python36/Scripts/tes
ting.py", line 11, in <module>
P()
File "C:/Users/Aditya
Shrivastava/AppData/Roaming/Python/Python36/Scripts/testing.py", line 5, in
P
M = [int(d) for d in str(N)]
UnboundLocalError: local variable 'N' referenced before assignment
【问题讨论】:
我不清楚你的描述。如果我输入 999 会发生什么?预期的输出是多少? 9+9+9 = 27 然后 2+7 = 9。所以最终答案是 9。 【参考方案1】:您正在使用递归来解决这个问题。简单地使用循环更有效:
def gimmeNumber(text):
""""Helper: Asks for input until valid integer number is inputted. Retuns the number"""
while True:
T = input(text).strip()
if T and T.isdigit():
T = int(T)
break
print("Thats not a number ...")
return T
def sumDigits(number):
return sum(int(x) for x in str(number))
T = gimmeNumber("How many numbers? ")
for _ in range(T):
s = 0
N = gimmeNumber("Give me a number: ")
# calculate the cross-sum
s = sumDigits(N)
while s > 9: # repeat while greater then 9
s = sumDigits(s)
print(s)
输入:4,然后是 999,888,333,111
输出:
9
6
9
3
正如@Arne 建议将gimmeNumber(text)
更改为使用try/except
而不是更适合python 的Ask forgiveness not permission 心态,我同意。
不过,上面的变体也适用,并且对于初学者来说更容易理解。这里是try/except
一个:
def gimmeNumber(text):
""""Helper: Asks for input until valid integer number is inputted. Retuns the number"""
while True:
try:
T = int(input(text).strip())
break
except ValueError as e:
print("Thats not a number ...")
return T
有关输入验证的更多信息,我建议您阅读Asking the user for input until they give a valid response 的答案。
【讨论】:
这可能是最好的解决方案,因为它首先避免了范围界定问题。 在gimmeNumber
中使用try..except
而不是if
来处理类型转换更加pythonic。
@Arne 你是对的,已编辑。仍然提供两者,因为我觉得第一个版本对于初学者来说更容易理解。【参考方案2】:
您得到的UnboundLocalError: local variable 'N' referenced before assignment
是由于在函数P()
中使用了N 而没有声明和初始化它。
N = int(input())
在循环内部,但在P()
的范围之外。循环中的最后一行P()
将调用函数P()
,而不是返回到分配N 的N = int(input())
。
我已将代码修改为
T = int(input())
for i in range(T):
N = int(input())
def P(N):
M = [int(d) for d in str(N)]
N = sum(M)
if N<10:
print(N)
else :
return P(N)
P(N)
【讨论】:
【参考方案3】:您可以通过将 N 作为参数传递给 P 函数来解决此问题。
T = int(input())
for i in range(T):
N = int(input())
def P(n):
M = [int(d) for d in str(n)]
n = sum(M)
if n<10:
print(n)
else :
P(n)
P(N)
如果您在函数 P 中设置 N 的值,python 会将其理解为创建具有该名称的局部变量。这个局部变量掩盖了函数外部使用的全局变量 N。所以,你最好将 N 作为参数传递给函数 P。
谢谢。
【讨论】:
【参考方案4】:python 中的函数声明了一个新的作用域,这就是为什么 N
在你的函数中不可见的原因。您可以通过将N
传递到内部范围来规避这种情况,如下所示:
T = int(input())
for i in range(T):
N = int(input())
def P(N):
M = [int(d) for d in str(N)]
N = sum(M) # this line was the actual culprit
if N<10:
print(N)
else :
return P(N)
P(N)
>>> 1 # test one time
>>> 12345 # cross total of 121212
6
Python 在写操作上是保守的。仅从外部范围变量中读取是可以的,但是重新分配名称 N
(如果您编写 N = sum(M)
会发生这种情况)使其严格检查该名称的 local 变量.
因此,它进一步假设该尚未声明的变量是您要在其上方的行中读取的位置 - 老实说,这有点误导。
有关 python 范围和命名空间的更多信息,请查看here。
【讨论】:
以上是关于如何在python中重复找到每个T数字的数字总和的数字总和,直到它成为一个数字?的主要内容,如果未能解决你的问题,请参考以下文章
如何找到添加两个变量的所有可能组合,每个变量都附加到一个乘数,总和为一个给定的数字(cin)?