[英]explanation to this recursion problem in python
check this sample code for backtracking, there are two ways I can append the variable i
to curr
before backtracking, the one here (not commented) updates the global ans
array, whereas the other way doesn't (shown below).:检查此示例代码以进行回溯,有两种方法可以 append 变量
i
在回溯之前进行curr
,此处(未注释)更新全局ans
数组,而另一种方法则不(如下所示):
n = 4
k = 2
ans = []
def backtrack(first, curr):
if len(curr)==k:
ans.append(curr)
for i in range(first, n+1):
# curr.append(i)
backtrack(i+1, curr+[i])
# curr.pop()
curr = []
backtrack(1, curr)
print("result = ",ans)
output here: result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
此处为 output:
result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
for the other way:另一种方式:
n = 4
k = 2
ans = []
def backtrack(first, curr):
if len(curr)==k:
ans.append(curr)
for i in range(first, n+1):
curr.append(i)
backtrack(i+1, curr)
curr.pop()
curr = []
backtrack(1, curr)
print("result = ",ans)
output here: result = [[], [], [], [], [], []]
此处为 output:
result = [[], [], [], [], [], []]
I wish to understand, what exactly changes here and why the global output array ans
behaves differently我想了解,这里到底发生了什么变化以及为什么全局 output 数组
ans
的行为不同
curr+[i]
creates a new object which gets passed to the next recursive call. curr+[i]
创建一个新的 object ,它被传递给下一个递归调用。 So whenever you then append curr
to ans
with this version, you append a new object showing you a snapshot of what curr
is which won't later get modified.因此,每当您使用此版本 append
curr
回答ans
时,您 append 一个新的 object 向您显示curr
是什么的快照,以后不会被修改。
When you instead use .append
and .pop
, you keep passing and having only one single object, so when you append it to ans
it is really that unique object that you append everytime again and again.当您改为使用
.append
和.pop
时,您会一直传递并且只有一个 object,因此当您将 append 回答为ans
时,它确实是您 append 每次一次又一次的唯一 object。 Then you will keep updating that unique object which will reflect on all element of ans
since they are the same object. Given at the end of processing curr
gets cleared you end up having only empty lists everywhere, even if at every step curr
had actually the value you wanted.然后,您将继续更新唯一的 object,它将反映
ans
的所有元素,因为它们是相同的 object。鉴于在处理结束时curr
被清除,您最终到处都只有空列表,即使在每一步curr
实际上都有你想要的价值。
You can see that by adding this print first to check that apart from this bug, everything still works the same in both cases as you would expect:你可以看到,通过首先添加这个打印来检查除了这个错误之外,在这两种情况下,一切仍然像你期望的那样工作:
def backtrack(first, curr):
print(first, id(curr), curr)
# ... and the rest
To fix the second version, you can pass a copy instead:要修复第二个版本,您可以传递一个副本:
curr.append(i)
backtrack(i+1, curr.copy())
curr.pop()
or copy when you append to ans
或在您将 append 复制到
ans
时复制
ans.append(curr.copy())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.