Python 浅拷贝、深拷贝

1. 浅拷贝

2. 深拷贝

3. 拷贝的其它方式

 

 

1. 浅拷贝

浅拷贝是对于一个对象的顶层拷贝。

通俗的理解是:拷贝了引用,并没有拷贝内容。

1 >>> a = [1, 2, 3]
2 >>> b = a
3 >>> id(a)
4 13081224
5 >>> id(b)
6 13081224
7 >>> a.append(4)
8 >>> b
9 [1, 2, 3, 4]

  

 2. 深拷贝

深拷贝是对一个对象所有层次(递归)的拷贝。

 1 >>> import copy
 2 >>> a = [1, 2, 3]
 3 >>> b = copy.deepcopy(a)  # 深拷贝
 4 >>> id(a)
 5 13098408
 6 >>> id(b)  # b和a已经不是指向同个对象
 7 12966280
 8 >>> a.append(4)
 9 >>> a
10 [1, 2, 3, 4]
11 >>> b
12 [1, 2, 3]

进一步理解深拷贝:

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = [a, b]  # 浅拷贝,对于列表c,创建了新的内存空间;但其中的a、b仅是引用
>>> c
[[1, 2, 3], [4, 5, 6]]
>>> a.append(7)
>>> c
[[1, 2, 3, 7], [4, 5, 6]]
>>>
>>> d = c
>>> id(c)
13097064
>>> id(d)
13097064
>>> e = copy.deepcopy(c)  # 深拷贝,e、a、b均创建了新的内存空间
>>> id(e)
12966280
>>> a.append(8)
>>> a
[1, 2, 3, 7, 8]
>>> c
[[1, 2, 3, 7, 8], [4, 5, 6]]
>>> e
[[1, 2, 3, 7], [4, 5, 6]]
>>> f = copy.copy(c)  # 浅拷贝,对于列表f,创建了新的内存空间;但其中的a、b仅是引用
>>> id(c)
13097064
>>> id(f)
13081128
>>> a.append(9)
>>> a
[1, 2, 3, 7, 8, 9]
>>> c
[[1, 2, 3, 7, 8, 9], [4, 5, 6]]
>>> f
[[1, 2, 3, 7, 8, 9], [4, 5, 6]]

deepcopy() 图示:

浅拷贝对不可变类型和可变类型的 copy 不同:

 1 >>> a = [1, 2, 3]
 2 >>> b = copy.copy(a)  # 浅拷贝可变类型,会新创建对象
 3 >>> id(a)
 4 13097480
 5 >>> id(b)
 6 13097672
 7 >>> a.append(4)
 8 >>> a
 9 [1, 2, 3, 4]
10 >>> b
11 [1, 2, 3]
12 >>>
13 >>> a = (1, 2, 3)
14 >>> b = copy.copy(a)  # 浅拷贝不可变类型,仅拷贝引用
15 >>> id(a)
16 24029512
17 >>> id(b)
18 24029512

  

3. 拷贝的其它方式

切片

 1 >>> a = "abc"
 2 >>> b = a[:]  # 不可变类型,浅拷贝
 3 >>> id(a)
 4 1280907951440
 5 >>> id(b)
 6 1280907951440
 7 >>>
 8 >>> a = [1, 2, 3]
 9 >>> b = a[:]  # 可变类型,深拷贝
10 >>> id(a)
11 1280908916552
12 >>> id(b)
13 1280908915784

列表、字典的copy方法

1 >>> a = {1: 2, 2: "a"}
2 >>> b = a.copy()  # 深拷贝,创建新对象
3 >>> id(a)
4 23759080
5 >>> id(b)
6 23759040

有些内置函数可以生成拷贝

 1 >>> a = [1, 2]
 2 >>> b = list(a)  # 拷贝可变类型,创建新对象
 3 >>> id(a)
 4 13097672
 5 >>> id(b)
 6 13213224
 7 >>> a = dict(a=1, b=2)
 8 >>> b = dict(a)  # 拷贝可变类型,创建新对象
 9 >>> id(a)
10 13107104
11 >>> id(b)
12 13106464
13 >>> a = (1, 2)
14 >>> b = tuple(a)  # 拷贝不可变类型,仅拷贝引用
15 >>> id(a)
16 13159912
17 >>> id(b)
18 13159912

 

posted @ 2020-02-23 21:14  Juno3550  阅读(137)  评论(0编辑  收藏  举报