如何在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)?

leetcode 40. 组合总和 II (python)

查找数组总和中的哪些数字到目标总和 [重复]

查找并打印总和为 100 的每个唯一组合,并返回 1 到 100 之间数字的所有此类组合的计数 [重复]

Leetcode刷题Python40. 组合总和 II

计算每个数字的4次幂的总和,为什么我得到错误的结果?