Python列表递归更改

Posted

技术标签:

【中文标题】Python列表递归更改【英文标题】:Python list recursive changes 【发布时间】: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 以引用新列表。它不会改变作为参数传入的原始列表 【参考方案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]

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

【讨论】:

以上是关于Python列表递归更改的主要内容,如果未能解决你的问题,请参考以下文章

查找列表中的最小元素(递归) - Python

递归与回溯:python列表组合问题

带有列表的 Python 基于轮次的递归

在python中使用递归来组合可变大小的列表

带有列表的Python递归返回无[重复]

如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]