Python递归可变参数传递错误:传入元组而非多参数
解决递归记忆化函数的参数数量错误问题
嘿,我来帮你搞定这个问题!你遇到的核心问题有两个:递归调用时没有解包参数列表,以及记忆化装饰器不支持可变位置参数,咱们一个个来解决。
问题1:递归调用的参数传递错误
你在递归调用fun1(p1tpn)的时候,p1tpn是一个列表[4,6],直接传进去的话,Python会把这个列表当作单个参数传给fun1,所以*arg会把它打包成元组([4,6],),导致函数只收到1个参数,而不是预期的两个。
解决方法很简单:用参数解包操作符*,把列表里的元素拆成单独的位置参数传递,也就是把fun1(p1tpn)改成fun1(*p1tpn)。这样[4,6]就会被拆成4和6两个参数传入fun1。
问题2:记忆化装饰器不支持可变参数
你现在的memoize装饰器只接受单个参数x,但fun1是用*arg定义的可变位置参数函数,所以装饰器必须适配这种情况。我们需要修改装饰器,让它能接收任意数量的位置参数,并用这些参数组成的元组作为缓存的键(因为元组是可哈希的,可以作为字典的键)。
修正后的装饰器应该是这样:
def memoize(f): memo = {} def helper(*args): # 用参数元组作为缓存键,因为args是可哈希的 if args not in memo: memo[args] = f(*args) return memo[args] return helper
完整修正后的代码
另外注意你原来的fun1里有个注释掉的if语句,对应的else没有匹配的if,我帮你调整了逻辑(假设你是想当第一个参数为1时返回1,否则继续递归):
def partition(collection): if len(collection) == 1: yield [ collection ] return first = collection[0] for smaller in partition(collection[1:]): # insert `first` in each of the subpartition's subsets for n, subset in enumerate(smaller): yield smaller[:n] + [[ first ] + subset] + smaller[n+1:] # put `first` in its own subset yield [ [ first ] ] + smaller def memoize(f): memo = {} def helper(*args): if args not in memo: memo[args] = f(*args) return memo[args] return helper @memoize # 用装饰器语法更规范,代替原来的fun1 = memoize(fun1) def fun1(*arg): lArg = len(arg) firstNumber = arg[0] print("I was called with", len(arg), "arguments:", arg) print("with arg type", type(arg)) argList = list(arg) print("argList is:", argList) print("first arg is:", arg[0]) p1tpn = argList[1:] print("rest of arg is:", p1tpn) if firstNumber == 1: return 1 # 当参数数量大于1时才递归,避免无参数调用报错 elif lArg > 1: return fun1(*p1tpn) else: # 处理只剩一个参数的情况,这里可以根据你的需求调整返回值 return 0 # 示例返回值,你可以改成自己需要的逻辑 # 测试调用 fun1(2,4,6)
关键修改点总结
- 递归调用时用
fun1(*p1tpn)代替fun1(p1tpn),解包参数列表 - 修改
memoize装饰器的helper函数为*args参数,用参数元组作为缓存键 - 用
@memoize装饰器语法代替手动赋值,更符合Python规范 - 完善
fun1的逻辑,避免参数不足时的递归错误
这样修改后,你调用fun1(2,4,6)时,递归调用会正确传递4和6两个参数,记忆化也能正常工作啦!
内容的提问来源于stack exchange,提问作者nate
相关产品推荐
相关产品推荐

