繁体   English   中英

递归函数不返回值

[英]Recursive Function Not Returning Value

此代码应该找到整数的数字之和。 当我运行它时,计算机只是处理了一段时间,然后什么也没有发生

def sum_of_digits(integer):
    numlist = list(str(integer))
    if len(numlist) == 0:
        result = 0
    elif len(numlist) == 1:
        result = numlist[0]
    else:
        midPoint = len(numlist) // 2
        result = sum_of_digits(numlist[:midPoint]) + 
        sum_of_digits(numlist[midPoint:])
    print(result)
    return result


sum_of_digits(123456)

这个答案并不数量转换为字符串(或其他可迭代),然后回数字。

def sum_of_digits (n: int, sum = 0) -> int:
  if n < 10:
    return n + sum
  else:
    return sum_of_digits (n // 10, sum + n % 10)

print(sum_of_digits(1))      # 1
print(sum_of_digits(12))     # 3
print(sum_of_digits(123))    # 6
print(sum_of_digits(1234))   # 10
print(sum_of_digits(12345))  # 15

另一个没有数据类型转换的简单解决方案:

def sum_of_digits(integer):
    if integer == 0:
        return 0
    else:
        return integer % 10 + sum_of_digits(integer // 10)

您已经严重混淆了您的数据类型。 命名某个integer并不能使其成为整数。 第一个电话你没问题。 如果您进行了任何基本的调试,您就会看到问题:您将整数转换为单字符字符串列表。

当您拆分列表并重复时,您将该半列表作为integer传递到您的函数中。 当您立即使用str(integer)将其转换为新字符串时,您会得到一个类似于"['1']"的字符串,而不是一个简单的字符数字。 当你把分解成一个列表时,你会得到['[', "'", '1', ']', "'"]作为numlist ......这是一个令人讨厌的无限递归。

首先,确保您的函数具有一致的接口:如果没有别的,请将半字符串重组为整数并将该值提供给您的递归调用。 其次,不要过于膨胀:您可以简单地将整数转换为字符串并处理单个数字; 无需从中列出清单。 第三,请参阅这个可爱的调试博客以寻求帮助。

最后,您可以在线研究其他解决方案。 这是一个常见的练习。 我不是要你复制程序——但是现在你已经很好地尝试了这个问题,你可以从其他人那里了解内部处理。

为了让您动起来,下面是我如何检测您的代码以进行调试:在进入和退出时print有用的东西,并延迟(睡眠)以便我有机会在有用的信息滚出屏幕之前中断程序。

from time import sleep

call = 0

def sum_of_digits(integer):
    global call

    call += 1
    id = call 

    print("ENTER", call, integer)

    numlist = list(str(integer))
    print("numlist", numlist)
    sleep(1)

    if len(numlist) == 0: 
        result = 0
    elif len(numlist) == 1:
        result = numlist[0]
    else:
        midPoint = len(numlist) // 2
        result = sum_of_digits(numlist[:midPoint]) + \ 
                 sum_of_digits(numlist[midPoint:])

    print("LEAVE", id, result)
    return result


test = [0, 1, 12]
for case in test:
    call = 0
    sum_of_digits(case)
    print("-------------------------")

输出:

ENTER 1 0
numlist ['0']
LEAVE 1 0
-------------------------
ENTER 1 1
numlist ['1']
LEAVE 1 1
-------------------------
ENTER 1 12
numlist ['1', '2']
ENTER 2 ['1']
numlist ['[', "'", '1', "'", ']']
ENTER 3 ['[', "'"]
numlist ['[', "'", '[', "'", ',', ' ', '"', "'", '"', ']']
ENTER 4 ['[', "'", '[', "'", ',']
numlist ['[', "'", '[', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '[', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ']']
^CTraceback (most recent call last):
  File "so.py", line 33, in <module>
    sum_of_digits(case)
  File "so.py", line 23, in sum_of_digits
    result = sum_of_digits(numlist[:midPoint]) + \
  File "so.py", line 23, in sum_of_digits
    result = sum_of_digits(numlist[:midPoint]) + \
  File "so.py", line 23, in sum_of_digits
    result = sum_of_digits(numlist[:midPoint]) + \
  File "so.py", line 15, in sum_of_digits
    sleep(1)
KeyboardInterrupt

您正在调用自己内部的函数。 此外,当您调用它时,您给它的是一个列表而不是整数,因此导致它遍历列表而不是您想要的数字。 您可能希望使用''.join返回整数而不是列表。

sum_of_digits(int(''.join(numlist[:midPoint]))))

即使你这样做了,你的函数仍然需要做更多的工作,你可能想要使用int()声明来确保你正在使用整数。

您也可以使用使用 for 循环的东西,它会以更有效的方式实现您的目标,但可能不是您想要的。

def sum_of_digits(integer):
    ans=0
    for i in str(integer):
        ans+=int(i) 
    return ans

尽管“什么也没发生”并没有提供太多信息,但您显然是以一种非常混乱的方式混合数据类型。

你的sum_of_digits函数接受一个整数作为参数,称它为integer并不能使它成为一个,你仍然需要确保使用正确的参数调用它。

当您使用sum_of_digits(numlist[:midPoint])sum_of_digits(numlist[midPoint:])递归调用它时,您传递的是一个字符串而不是整数,这就是出错的地方,请继续努力。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM