python参数引用传递踩坑实录
1 问题描述
写字符串全排列的时候,预期res变量应当返回所有全排列组合。
def check(nums, ind, res):
if len(nums) == ind:
res.append(nums)
return
for i in range(ind, len(nums)):
nums[i], nums[ind] = nums[ind], nums[i]
check(nums, ind + 1, res)
nums[i], nums[ind] = nums[ind], nums[i]
res = []
check([1, 2, 3], 0, res)
print(res)
但是结果却是:
结果怎么和想象中不太一样…在函数内打印看看
def check(nums, ind, res):
if len(nums) == ind:
print(nums)
res.append(nums)
return
for i in range(ind, len(nums)):
nums[i], nums[ind] = nums[ind], nums[i]
check(nums, ind + 1, res)
nums[i], nums[ind] = nums[ind], nums[i]
res = []
check([1, 2, 3], 0, res)
print(res)
打印结果如下:
(っ °Д °;)っ明明函数内处理的结果是正确的,怎么append之后结果却不一样了?
2 问题原因
因为res.append(nums)
实际上是添加了nums列表的地址,而不是nums列表本身,check函数执行完毕后,res内所有元素实际上都存放的是nums列表的地址👇
3 知识扩展 & 解决方案(深浅拷贝)
3.1 深浅拷贝
内容参考:python深浅拷贝
- 直接赋值
- 浅拷贝(copy)
拷贝父对象,不拷贝对象内部的子对象 - 深拷贝(deepcopy)
拷贝父对象也拷贝子对象
实例:
arr1 = [1, 2, ['a', 'b']]
import copy
arr2 = copy.copy(a)
arr3 = copy.deepcopy(a)
3.2 解决方案
就全排列例子而言,因为列表中元素均为数值类型,使用深浅拷贝都可,将res.append(nums)
修改为nums.append(nums.copy())