Python列表的赋值,浅拷贝和深拷贝详解【Python】

最近在刷leetcode的回溯题时,涉及到列表的拷贝,在此记录下列表拷贝的不同。
下文的例子多数借鉴于https://www.cnblogs.com/dfc001/p/11526151.html

1. 列表的赋值

赋值主要是设定了一个变量的引用,赋值主要方式是通过等于号’=’。

a = [1, 2, [3]]
b = a
b.append(4)
print(a, id(a))
print(b, id(b))

输出结果

[1, 2, [3], 4] 4457931016
[1, 2, [3], 4] 4457931016

可以看到,在赋值列表b以后对b进行了更改,但是输出却会发现a也会同时改变,并且ab的id是一样的,也就是说在python中对于列表的赋值,实际上是改变了原指针的指向,而并不会重新开辟新的内存空间。因此对于赋值后的列表做增删改操作,其实就是在原列表上做。

2. 列表的浅拷贝

python列表的浅拷贝方式一般是copy()函数和列表切片。
例1

a = [1, 2, [3]]
b = a.copy()  # b = a[:]
b.append(4)
b[2].append(4)
print(a, id(a))
print(b, id(b))

输出结果

[1, 2, [3, 4]] 4410188040
[1, 2, [3, 4], 4] 4410340104

例2

a = [[1, 3], {'a': 'b'}, 4, {4}]
b = a[:]
b[0].append(5)
b[1]['c'] = 'd'
b[3].add(10)
b[2] = 6
print(a, id(a))
print(b, id(b))

输出结果

[[1, 3, 5], {'a': 'b', 'c': 'd'}, 4, {10, 4}] 4316430600
[[1, 3, 5], {'a': 'b', 'c': 'd'}, 6, {10, 4}] 4316582664

可以看到,浅拷贝对于列表中存在的可变对象如列表,集合,字典也是引用的原对象的地址空间,所以会一同改变。而对于列表中存在的数值型数据这些不可变对象,浅拷贝会直接创建新的地址空间用以保存。

3. 列表的深拷贝

python列表的深拷贝就只有copy.deepcopy()一种了。

import copy

a = [1, 2, [3]]
b = copy.deepcopy(a)
b.append(4)
b[2].append(4)
print(a, id(a))
print(b, id(b))

输出结果

[1, 2, [3]] 4545831688
[1, 2, [3, 4], 4] 4545831816

深拷贝就是新建额外的内存空间,并将原对象的值复制过去。怎样改变都不会影响原对象的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章