求1-1000内迭代数字平方和为1的数,递归报错maximum recursive density exceeded
解决递归深度超限问题并实现1-1000的快乐数查找
嘿,我来帮你排查这个问题!你的代码里有几个明显的问题导致了递归深度超限,还有逻辑上的bug,咱们一步步来理清楚:
代码里的核心问题
- 函数定义位置错误:你把
digisum和iteration放在了for循环内部,这意味着每遍历一个数就重新定义一次函数,完全没必要,还会引发作用域混乱。应该把函数定义移到循环外面。 digisum无返回值:这个函数计算了各位数字的平方和,但没有用return返回结果,调用它时会得到None,直接导致后续递归逻辑崩溃。- 变量作用域错误:
iteration函数里直接使用的x是digisum的局部变量,外部根本访问不到,这会触发未定义变量的错误(你先遇到递归超限是因为其他逻辑问题提前爆发了)。 - 未处理循环陷阱:有些数的迭代会进入无限循环,比如4→16→37→58→89→145→42→20→4,永远到不了1,递归会无限调用下去,直接触发
maximum recursion depth exceeded错误。 - 循环范围不符合需求:你用了
range(0,1000),但题目要求的是1到1000的范围,0的平方和是0,不符合条件。
修复后的实现方案
方案1:迭代版本(更稳妥,无递归深度问题)
这个版本用迭代代替递归,同时用集合记录已出现的数,避免进入无限循环:
def get_digit_square_sum(n): total = 0 while n > 0: digit = n % 10 total += digit ** 2 n = n // 10 return total def is_happy_number(n): seen = set() while n not in seen: seen.add(n) n = get_digit_square_sum(n) if n == 1: return True # 如果出现重复数,说明进入循环,不可能到1 if n in seen: return False # 遍历1到1000的所有数 for num in range(1, 1001): if is_happy_number(num): print(num)
方案2:递归版本(修复递归逻辑,避免无限调用)
如果偏好递归写法,可以通过传递集合跟踪已访问的数,防止无限递归:
def get_digit_square_sum(n): return sum(int(c)**2 for c in str(n)) def is_happy_number_recursive(n, seen=None): # 初始化已访问集合 if seen is None: seen = set() # 找到1,说明是目标数 if n == 1: return True # 出现重复数,进入循环,直接返回False if n in seen: return False seen.add(n) # 递归调用下一次平方和计算 return is_happy_number_recursive(get_digit_square_sum(n), seen) # 遍历1到1000的所有数 for num in range(1, 1001): if is_happy_number_recursive(num): print(num)
这两个版本都能正确找出1到1000范围内,迭代各位数字平方和最终得到1的数(这类数也叫快乐数),而且不会再出现递归深度超限的问题。
内容的提问来源于stack exchange,提问作者Soumonos




