Python递归疑问:sum_digits函数替换+为*后为何返回1而非21?
问题原因解析:运算符优先级导致递归结果不符合预期
嘿,这个问题的根源其实是运算符优先级在搞鬼!咱们把修改后的递归过程拆解开,就能一眼看出问题所在了。
首先先看你修改后的函数(应该是没给n%10加括号的版本):
def sum_digits(n): if n // 10 == 0: return n else: return sum_digits(n // 10) * n % 10 # 这里的运算顺序是关键!
先回忆原加法函数为什么没问题
原加法函数里,+的优先级比%低,所以会先计算n%10(取最后一位数字),再和sum_digits(n//10)的结果相加,完全符合你的预期:
sum_digits(137) = sum_digits(13) + 7 sum_digits(13) = sum_digits(1) + 3 sum_digits(1) = 1 最终:1 + 3 + 7 = 11
乘法版本的问题出在哪?
但改成*之后,规则变了——Python里*和%的优先级是相同的,并且遵循左结合的计算顺序(从左到右依次执行)。所以你写的sum_digits(n//10) * n % 10会被Python解析成:
(sum_digits(n//10) * n) % 10
而不是你预期的:
sum_digits(n//10) * (n % 10)
咱们一步步拆解sum_digits(137)的执行过程,就能看到结果是怎么来的:
- 调用
sum_digits(137):137//10=13≠0,所以计算sum_digits(13) * 137 % 10 - 调用
sum_digits(13):13//10=1≠0,计算sum_digits(1) * 13 % 10 - 调用
sum_digits(1):1//10=0,直接返回1 - 回到
sum_digits(13):计算1 * 13 % 10 = 13 % 10 = 3,返回3 - 回到
sum_digits(137):计算3 * 137 % 10 = 411 % 10 = 1,返回1
这就是为什么最终结果是1,而不是你想要的21。
怎么修复?
只需要给n%10加上括号,明确告诉Python先计算取模运算,再做乘法:
def product_digits(n): if n // 10 == 0: return n else: return product_digits(n // 10) * (n % 10) # 括号改变运算顺序
现在调用product_digits(137),就会得到1 * 3 * 7 = 21的正确结果啦!
内容的提问来源于stack exchange,提问作者pythonewbie
相关产品推荐
相关产品推荐

