【问题标题】:Python list recursive changesPython列表递归更改
【发布时间】:2015-12-07 11:48:13
【问题描述】:

我在尝试以递归方式将数字序列添加到列表时遇到了错误。例如。如果输入是 [5,3,9],我做 [5+1,3+2,9+3] 并输出 [6,5,12]。我想以递归方式执行此操作,因此我正在执行此操作并将其添加到列表的越来越小的部分,如下所示:

def add_position_recur(lst, number_from=0):
    length = len(lst)
    # base case
    if (length <= 1):
        lst = [x+1 for x in lst]
        print "last is", lst
    else:
        lst = [x+1 for x in lst]
        print "current list is", lst
        add_position_recur(lst[1:], number_from)
        return lst

不过,问题在于,这只是将 1 加到列表的每个元素上。错误在哪里?这与我在基本情况下返回列表的方式有关吗?

【问题讨论】:

  • number_from 是做什么用的?它在您的代码中的使用为零。请注意,当您执行 lst = ... 时,您正在更改您的 lst 以引用新列表。它不会改变作为参数传入的原始列表

标签: python list recursion return tail-recursion


【解决方案1】:

目前,您只是将列表的每个值加 1。

lst = [x+1 for x in lst]

相反,您应该在 lst 中每次迭代 x 时增加一个添加到 x 的变量。

lst = [x+(lst.index(x)+1) for x in lst]

此解决方案假定您希望添加到 x 的数字取决于其在列表中相对于列表开头的位置,而不是取决于 x 相对于 >1 的第一个元素的位置。意思是,您想将 1 或 3 添加到以下列表中的值 2 中吗?上面的解决方案增加了三个。

lst = [0.5, 0.1, 2, 3]

【讨论】:

  • 不要[x+(lst.index(x)+1) for x in lst],有重复项的时候就不行了,而且真的很慢。使用enumerate[x+(i+1) for i,x in enumerate(lst)]
  • @DanD。更好的是,使用enumeratestart 参数来避免额外的算术:[x+i for i,x in enumerate(lst, start=1)]
【解决方案2】:

当您向下递归调用堆栈时,您切片 lst 会创建一个新列表,这与您返回的内容不同,因此您只会返回您在第一次调用中应用到列表的更改到函数,丢失堆栈中的所有更改:

>>> add_position_recur([1,2,3])
[2, 3, 4]

这应该返回[2, 4, 6]
您需要考虑在退出时重新组合列表以进行更改。

return [lst[0]] + add_position_recur(lst[1:], number_from)

你需要return lst 在你的基本情况下:

def add_position_recur(lst, number_from=0):
    length = len(lst)
    # base case
    if (length <= 1):
        lst = [x+1 for x in lst]
        return lst
    else:
        lst = [x+1 for x in lst]
        return [lst[0]] + add_position_recur(lst[1:], number_from)
>>> add_position_recur([1,2,3])
[2, 4, 6]

但是,这是一种非常复杂的递归方法。基本情况是空列表是惯用的,否则取头部并沿尾部递归。所以要考虑使用number_from

def add_position_recur(lst, number_from=1):
    if not lst:
        return lst
    return [lst[0]+number_from] + add_position_recur(lst[1:], number_from+1)

>>> add_position_recur([1,2,3])
[2, 4, 6]

这还有一个优点(?)不改变传入的lst

【讨论】:

    【解决方案3】:

    你为什么不做这样的事情:

    def func(lon, after=[]):
        if not l:
            pass
        else:
            v = len(lon) + lon[-1]
            after.append(v)
            func(lon[:-1], after)
            return after[::-1]
    

    您提供的示例的函数输出与您想要的匹配。

    【讨论】:

      猜你喜欢
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多