You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:44:17