今天在刷LeetCode第78题子集时,遇到了一个很奇怪的现象,现在记录如下。
先把题目原题贴出来:
这是一道回溯算法题,按照解题思路本来写成:
result = []
def backtrack(nums, path, start):
result.append(path)
print('now the result is :{}\n'.format(result))
for i in range(start, len(nums)):
path.append(nums[i])
print("now the path is:{}\n".format(path))
backtrack(nums, path, i + 1)
path.pop()
看起来是没有任何问题的。但是在输出时会发现结果是
也就是result
里只保留了最后一次传入的path值,并且这个值还覆盖了前面的值。
这主要是因为python中分可变和不可变两种数据类型,举个例子
foo = ['hi']
print(foo)
# Output: ['hi']
bar = foo
bar += ['bye']
print(foo)
# Output: ['hi', 'bye']
我们看到此时变量foo和bar的值是一样的。这就是对象可变性导致的,每当我们将一个变量赋值为另一个可变类型变量时,对这个数据的任意改动都会同时反映在两个变量,新变量只是老变量的一个别名,该情况只针对可变数据类型。
那么在本题里,代码result.append(path)
传递的实际上是path
的地址,当path
的内容发生变化时,result
里的内容也会发生变化,因此应该写作result.append(list(path))
即新建一个对象并作为参数,这样就不会再发生改变了。