Python 递归问题
鉴于: 我希望返回以下代码:Python 递归问题,python,recursion,Python,Recursion,鉴于: 我希望返回以下代码: numma = [1,2,3,4], n = 7 相反,它返回一个包含以下内容的四个副本的列表: [[1,2,3],[1,2,4]] [1,2,4] 及六份: [[1,2,3],[1,2,4]] [1,2,4] 该脚本旨在按顺序获取列表编号=numma的元素,并与它们一起形成一个新的列表(此_链),只要此_链中的元素总和不超过n=7 当添加新元素将打破该条件时,此\u链的列表将附加到另一个列表(所有\u链),并且该过程将再次开始。如果原始列表(编号)中的元
numma = [1,2,3,4], n = 7
相反,它返回一个包含以下内容的四个副本的列表:
[[1,2,3],[1,2,4]]
[1,2,4]
及六份:
[[1,2,3],[1,2,4]]
[1,2,4]
该脚本旨在按顺序获取列表编号=numma的元素,并与它们一起形成一个新的列表(此_链),只要此_链中的元素总和不超过n=7
当添加新元素将打破该条件时,此\u链的列表将附加到另一个列表(所有\u链),并且该过程将再次开始。如果原始列表(编号)中的元素已用完,则当前this_链将附加到所有_链,脚本完成,并返回名为all_链的列表(列表)
当我一步一步地运行它时,它会遵循预期的行为,但在到达return语句(步骤84)时,箭头不会返回所有的_链和finish,而是向下移动半步,然后跳回第一个语句(对于I in
…)。然后它返回并将当前this_链的另一个副本附加到所有_链,以此类推,执行66个额外步骤并返回我上面提到的输出
有人建议我迭代一个元组,而不是一个列表,但是因为我想从迭代序列中删除元素,所以我不知道怎么做
我很困惑。我想问的四个问题,按重要性排序如下:
[1,2,3,4]
def-chain(数字,n,所有\u-chain=[],总和=0,此\u-chain=[]):
对于范围内的i(len(数字)):
如果数字[i]不在此_链中:
总和+=数字[i]
如果和
为什么程序在到达return语句时没有完成?
我相信返回语句总是会终止任何脚本
返回不终止脚本;它离开当前例程并将控制权返回给调用它的例程。当您进行递归调用时,它只是将控制权返回给调用它的自身的“旧”版本
鉴于上述行为,为什么脚本最终
结束,而不是继续将有效列表的副本附加到列表中
叫全链
它的结束是因为所有活动调用最终都会到达函数的底部,从而结束它们的执行
为什么脚本会将无效元素附加到所有\u链的列表中,
也就是说,元素总和大于n=7的列表
问题是,当您返回尝试添加4时,您认为您拥有的列表是[1,2],但它实际上是[1,2,3],因为。。。好吧,看看下一点
为什么所有_链中的元素都已删除(或修改),所以
它们不存在于最终输出中,即使它们存在
以前是否将所有链附加到列表中
无论在何处附加到列表,都会将引用附加到原始列表,而不是本地副本。这来自于使用可变对象(正如@tobias_k已经提到的)。因此,当您将[1,2,3]添加到列表中(多次)时,所有这些都是相同的对象。当您后来错误地将4追加到列表中(认为列表中只有[1,2])时,您将所有引用都更改为[1,2,3,4]。我已经在下面的代码中修复了这个问题
最后,由于缺少return语句,您有了所有这些额外的列表;不要在应该停止时停止,而是遍历函数的其余部分,进行更多调用,并找到相同解决方案的更多副本
我在你的代码中添加了一些东西,这样你就可以观察执行情况了。最重要的是,我添加了一些丑陋但有用的print语句来跟踪执行。我有一些模块来处理缩进、计数和参数打印,它们的可读性更高,你可以通过实验来看看什么是最可读的
我还将直接的追加操作替换为副本,这样您可以更好地区分问题,并从错误中学习更多内容
记住,好的选择来自经验。
经验来自错误的选择
def chain(numbers, n, all_chains=[], sum=0, this_chain=[]):
for i in range(len(numbers)):
if numbers[i] not in this_chain:
sum += numbers[i]
if sum <= n:
this_chain.append(numbers[i])
chain(numbers, n, all_chains, sum, this_chain)
else:
if this_chain not in all_chains:
all_chains.append(this_chain)
mocha = numbers[:]
mocha.remove(this_chain[-1])
chain(mocha, n, all_chains, sum=0, this_chain=[])
all_chains.append(this_chain)
return all_chains
numma = [1,2,3,4]
chain(numma, 7, chains=[], sum=0, this_chain=[])
为什么程序在到达return语句时没有完成?
我相信返回语句总是会终止任何脚本
返回不终止脚本;它离开当前例程并将控制权返回给调用它的例程。当您进行递归调用时,它只是将控制权返回给调用它的自身的“旧”版本
鉴于上述行为,为什么脚本最终
结束,而不是继续将有效列表的副本附加到列表中
叫全链
它的结束是因为所有活动调用最终都会到达函数的底部,从而结束它们的执行
为什么脚本会将无效元素附加到所有\u链的列表中,
也就是说,元素总和大于n=7的列表
问题是,当您返回尝试添加4时,您认为您拥有的列表是[1,2],但它实际上是[1,2,3],因为。。。好吧,看看下一点
为什么所有_链中的元素都已删除(或修改),所以
它们不存在于最终输出中,即使它们存在
以前是否将所有链附加到列表中
无论在何处附加到列表,都会附加一个