列表是可变数据类型,它的值可以增加,删除或改变
字符串是不可变数据类型,它不能被更改
引用
变量存储的是对计算机内存位置的引用,这些位置存储了值。
List1 = [1,2,3]
List2 = List1
List2[1] = 'abc'
print(List1)
>>> [1, 'abc', 3]
print(List2)
>>> [1, 'abc', 3]
print(id(List1), id(List2))
>>> 2021813609032 2021813609032
当创建列表时,只是将对它的引用赋给了变量List1, List2 = List1只是将列表引用复制到了List2变量,而不是列表值本身,这就意味这存储在List1 和 List2 变量中的值指向的是同一个列表,因此改变了List2变量指向的列表同时,List1指向的列表也发生了改变。
引用时List1和List2的引用ID是一样的。
传递引用
当函数被调用时,参数的值被复制给可变元素,对于列表,这意味着可变元素得到的是引用的复制。
def func(someList):
someList.append("append")
List1 = [1,2,3]
func(List1)
print(List1)
>>> [1, 2, 3, 'append']
尽管List1和someList变量包含了不同的引用,但是他们都指向相同的列表,当func()函数被调用时,没有返回值来为List1变量赋予新值,直接就地修改了列表,因此返回[1, 2, 3, ‘append’]
浅复制与深复制
浅复制只是复制的是浅层次的数据结构(不可变元素)
深拷贝既可以复制不可变元素,也可以复制可变元素。
import copy
List1 = [1,2,3,['a','b']]
List2 = copy.copy(List1)
List3 = copy.deepcopy(List1)
print("原列表 列表id =",id(List1),"不可变元素id =",id(List1[1]),"可变元素id =",id(List1[3]))
print("浅拷贝 列表id =",id(List2),"不可变元素id =",id(List2[1]),"可变元素id =",id(List2[3]))
print("深拷贝 列表id =",id(List3),"不可变元素id =",id(List3[1]),"可变元素id =",id(List3[3]))
>>> 原列表 列表id = 2984762441096 不可变元素id = 140736276714560 可变元素id = 2984762441224
>>> 浅拷贝 列表id = 2984762441480 不可变元素id = 140736276714560 可变元素id = 2984762441224
>>> 深拷贝 列表id = 2984762478088 不可变元素id = 140736276714560 可变元素id = 2984762476872
浅复制时,List2的列表引用的ID改变了,但是里面可变元素的ID和源列表一样。
深复制时,List3的列表引用的ID和里面的可变元素(列表)ID改变了。
对List1分别进行如下操作:
List1.append(4)
print(List1)
print(List2)
print(List3)
>>> [1, 2, 3, ['a', 'b'], 4]
>>> [1, 2, 3, ['a', 'b']]
>>> [1, 2, 3, ['a', 'b']]
List1[1] = 'change'
print(List1)
print(List2)
print(List3)
>>> [1, 'change', 3, ['a', 'b'], 4]
>>> [1, 2, 3, ['a', 'b']]
>>> [1, 2, 3, ['a', 'b']]
此时List1、List2、List3均指向独立的列表,修改Lisrt1中的不可变元素时,List2、List3不受影响。
List1[3].append('c')
print(List1)
print(List2)
print(List3)
>>> [1, 2, 3, ['a', 'b', 'c']]
>>> [1, 2, 3, ['a', 'b', 'c']]
>>> [1, 2, 3, ['a', 'b']]
修改Lisrt1中的可变元素时,浅复制List2中的可变 元素也会跟着改变,而深复制List3则不受影响。