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深浅拷贝

  1. 直接赋值
  2. 浅拷贝(copy)
    拷贝父对象,不拷贝对象内部的子对象
  3. 深拷贝(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())