Python中的递归实现列表追加

10
我想以递归的方式将内容添加到列表中,但我无法编写一个有效的函数。该函数接受两个参数timesdatatimes应该是添加数据的次数。
这是我目前的代码:
def replicate_recur(times, data):
    result2 = []
    if times == 0:
        result2.append(data)
    else:
        result2.append(data)
        replicate_recur(times - 1, data)
    return result2

result2是本地变量,因此您必须提到result2.extend(replicate_recur(times - 1, data))。 - Kajal
你可以通过使用 result.extend(data*times) 来轻松实现这一点。 - Kajal
我收到了使用递归的指令。 - Nix
@MosesKoledoye的回答应该被接受。 - Adirio
6个回答

5

您可以使用一个中间列表,在每个递归调用中添加内容。这样可以避免当前遇到的重新定义问题:

def replicate_recur(times, data, result=None):
    if result is None:  # create a new result if no intermediate was given
        result = []
    if times == 1:
        result.append(data)
    else:
        result.append(data)
        replicate_recur(times - 1, data, result)  # also pass in the "result"
    return result

当被调用时:

>>> replicate_recur(4, 2)
[2, 2, 2, 2]

3
为了让您的代码工作,需要使用extend将当前执行中的列表与下一个递归调用的输出扩展在一起。此外,递归的最低深度应该由times = 1定义:
def replicate_recur(times, data):
    result2 = []
    if times == 1:
        result2.append(data)
    else:
        result2.append(data)
        result2.extend(replicate_recur(times - 1, data))
    return result2

另外,您可以使用以下方法简单地复制您的列表:

def replicate(times, data):
    return [data]*times

很好,完美解决了。所以我的代码问题在于每次函数递归时我的列表都是空的? - Nix
不是这样的,你调用了replicate_recur但没有对返回的结果进行任何操作。如果这是一个真实的用例而不是为了学习递归函数的工作原理,请使用其他提供的方法。 - Adirio

2

你可以使用xrange来实现,除非这是一次编码测试,否则没有使用递归的必要。

def replicate(times, data):
    result2 = []
    for i in xrange(times):
        result2.append(data)
    return result2

同样的功能可以用递归方式编写,像这样:

def replicate_recur(times, data, listTest=None):
    # If a list has not been passed as argument create an empty one
    if(listTest == None):
        listTest = []
    # Return the list if we need to replicate 0 more times
    if times == 0:
        return listTest
    # If we reach here at least we have to replicate once
    listTest.append(data)
    # Recursive call to replicate more times, if needed and return the result
    replicate_recur(times-1, data, listTest)
    return listTest

我已经有一个可行的方案了,正在尝试使用递归实现相同的功能。下面有一个完美的答案。 - Nix
我已经更新了我的答案,请看一下,如果您认为这就是您需要的,请接受它。 - pushpendra chauhan
建议进行一些编辑,以改善您的编码风格并增强功能,请接受它们。但是,这不应该是被接受的答案。缩写形式比@MosesKoledoye的版本更糟糕:[data]*times,并且在递归中使用可变方法.append()而不返回(它确实返回但没有被使用,因此就像虚拟未返回)对于初学者来说很难理解。 - Adirio

0
Python使用“对象引用方式传递参数”,这就是为什么在您的情况下以下任一代码都应该有效。
def replicate_recur(times, data, result2 = []):
    if times == 1:
        result2.append(data)
    else:
        result2.append(data)
        replicate_recur(times - 1, data)
    return result2

被调用时:

>>> replicate_recur(4, 2)
[2, 2, 2, 2]

或者,您可以创建result2列表并将其作为参数传递给函数。该参数是“按对象引用传递”的,因此在函数内部也会修改相同的结果对象。

def replicate_recur(times, data):
    if times == 1:
        result2.append(data)
    else:
        result2.append(data)
        replicate_recur(times - 1, data)
    return result2

被调用时:

>>> result2 = []
>>> replicate_recur(4, 2)
[2, 2, 2, 2]

请参考以下链接,了解有关对象引用传递的更多信息。 Python:对象引用传递


0
因为你每次都重新定义result2。将result2放在函数外面,它应该可以工作。
另外,如果data是一个列表,你可以考虑使用data*times来复制,或者简单地执行。
(result2.append(data))*times

因为列表将会重复自身。例如[1,2]*2 = [1,2,1,2]。 - Abhishek J

0
在递归中,每次调用replicate_recur时,都会在新的命名空间中创建一个全新的result2。
[data] * times

会实现你想要达到的目标。


这将会对我的数据进行乘法运算,而不是重复它。 - Nix
1
你看到数据周围的方括号了吗?我正在乘以一个包含你的数据的列表,这相当于重复。 - Vinayak Kaniyarakkal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接