十进制转二进制递归函数显式修改value变量结果不同的原因是什么?
两种递归写法结果不同的核心原因
错误写法(第一种)的执行逻辑
你第一种写法的问题在于提前修改了当前函数作用域内的value变量,导致回溯阶段追加值的时候用的不是函数初始传入的原值:
def dec2bin(value,lis=[]): if value>1: value=value//2 # 这里直接修改了当前作用域的value值 dec2bin(value) lis.append(value%2) # 回溯时用的是修改后的value,不是初始传入的值 return lis print(dec2bin(5))
我们拆解执行步骤:
- 调用dec2bin(5),value=5>1,执行
value=5//2=2,调用dec2bin(2) - 进入dec2bin(2),value=2>1,执行
value=2//2=1,调用dec2bin(1) - 进入dec2bin(1),不满足判断条件,追加
1%2=1到列表,列表为[1],返回上一层 - 回到dec2bin(2)的作用域,此时value已经被修改为1,追加
1%2=1,列表为[1,1],返回上一层 - 回到dec2bin(5)的作用域,此时value已经被修改为2,追加
2%2=0,最终得到[1,1,0]的错误结果
正确写法(第二种)的执行逻辑
第二种写法没有修改当前作用域的value,只是把计算后的值作为参数传给下一层递归,回溯时用的是函数初始传入的原值:
def dec2bin(value,lis=[]): if value>1: dec2bin(value//2) # 仅把计算值传给下一层,当前作用域的value不变 lis.append(value%2) return lis print(dec2bin(5))
拆解执行步骤:
- 调用dec2bin(5),value=5>1,直接传入
5//2=2调用dec2bin(2),当前作用域value仍为5 - 进入dec2bin(2),value=2>1,传入
2//2=1调用dec2bin(1),当前作用域value仍为2 - 进入dec2bin(1),不满足判断条件,追加
1%2=1到列表,列表为[1],返回上一层 - 回到dec2bin(2)的作用域,value仍为2,追加
2%2=0,列表为[1,0],返回上一层 - 回到dec2bin(5)的作用域,value仍为5,追加
5%2=1,最终得到[1,0,1]的正确结果
额外注意点
你的代码用到了lis=[]作为默认参数,这是Python的常见坑点:可变默认参数会在函数定义时初始化,多次调用函数会共用同一个列表对象。如果多次调用这个函数,会出现结果累加的异常,建议修改为如下写法:
def dec2bin(value, lis=None): if lis is None: lis = [] if value>1: dec2bin(value//2, lis) lis.append(value%2) return lis
内容的提问来源于stack exchange,提问作者Sidhartha Mohapatra
相关产品推荐
相关产品推荐

