话不多说,我们还是先来看下代码:
代码1:
def fun(lst):
lst[0]=1
print(lst,222)
lst=[4,5,6,7]
fun(lst)
print(lst)
'''
输出结果是:
[1, 5, 6, 7] 222
[1, 5, 6, 7]
'''
再看代码2:
def fun(lst):
lst=lst[:]
lst[0]=1
print(lst,222)
lst=[4,5,6,7]
fun(lst)
print(lst)
'''
输出结果是:
[1, 5, 6, 7] 222
[4, 5, 6, 7]
'''
为什么代码1在函数会导致外部lst的改变呢?
我们要知道,数据有两种类型:一是可变类型,其实我更倾向于表述为引用类型,即变量名指向的都是数据的存储地址,这个地址是可以多个变量名共享的,如list,set,dict;二是不可变类型,这个我更倾向于表述为值类型,即开辟新的内存,复制原地址的数据,如int,str。
代码块一,二中实参lst是可变类型数据,此时传入函数fun的形参lst接收到的是外部lst的内存地址,实参lst和形参lst的数据是共享的,所以代码块一fun函数内部执行lst[0]=1,其实是修改的共享的数据,所以代码块一输出相同的list。
我们再看代码块二,多了一个lst=lst[:]。这里涉及到一个关于切片复制话题,切片复制是新开内存存放list的部分值(或全部值),这里示例是复制全部数据。此时实参lst和形参lst不共享同个内存地址。所以代码块二执行lst[0]=1,不会影响到实参lst。
最后,其实把参数名改一下执行也是同样的结果,在这里使用相同的名是为了更加混乱,好让大家更能明白怎么回事。其中若有不对的地方,请各位大佬指正,不甚感激!