Python-浅拷贝、深拷贝

  1. 浅拷贝、深拷贝
    1. 浅拷贝:
    2. 深拷贝

浅拷贝、深拷贝

浅拷贝:

所谓浅拷贝,指的是:对于某个对象,虽然创建了与该对象具有相同值的另一个对象,但是,这两个对象内部嵌套的对应子对象全都是同一个对象。简单的说,外部进行了拷贝,内部没有拷贝。

以下几种方式进行的拷贝均是浅拷贝:
1、使用切片操作[:]
2、使用列表、字典、集合的copy()方法
3、使用内置函数list()、dict()、set()
4、调用copy模块的copy()函数

#!/usr/bin/python3

import copy

L1 = [[1, 2, 3], 4]
L2 = copy.copy(L1)

print('id(L1) ={}'.format(id(L1)))
print('id(L2) ={}'.format(id(L2)))

print('id(L1[0]) ={}'.format(id(L1[0])))
print('id(L2[0]) ={}'.format(id(L2[0])))

print('id(L1[1]) ={}'.format(id(L1[1])))
print('id(L2[1]) ={}'.format(id(L2[1])))
[root@lyucan ~]# ./5.py
id(L1) =140528250703048
id(L2) =140528250250888
id(L1[0]) =140528250114568
id(L2[0]) =140528250114568
id(L1[1]) =140528249476800
id(L2[1]) =140528249476800

当浅拷贝时,对拷贝对象的其中一个元素进行修改,如果该元素是可变对象,那么其他拷贝的对象也会随之被修改。
注意!无论是浅拷贝还是深拷贝,对于不可变对象的元素,修改其中一个,另一个都不会随之改变,和深浅拷贝无关。

>>> L1 = [[1, 2], 3]
>>> L2 = L1[:]
>>>
>>> L1
[[1, 2], 3]
>>> L2
[[1, 2], 3]
>>>
>>> L1[0].append(3)
>>> L1
[[1, 2, 3], 3]
>>>
>>> L2
[[1, 2, 3], 3]
>>>
>>> L1[1] = 5
>>> L1
[[1, 2, 3], 5]
>>> L2
[[1, 2, 3], 3]

深拷贝

可以调用copy模块中的deepcopy()函数实现。

指的是:对于某个对象,创建与该对象有相同值的另一个对象,同时,这两个对象内部嵌套的对应子对象不是同一个对象。简单地说,外部和内部都进行了拷贝。

#!/usr/bin/python3

import copy

L1 = [[1, 2, 3], 4]
L2 = copy.deepcopy(L1)

print('id(L1) ={}'.format(id(L1)))
print('id(L2) ={}'.format(id(L2)))

print('id(L1[0]) ={}'.format(id(L1[0])))
print('id(L2[0]) ={}'.format(id(L2[0])))

print('id(L1[1]) ={}'.format(id(L1[1])))
print('id(L2[1]) ={}'.format(id(L2[1])))
[root@lyucan ~]# ./5.py
id(L1) =140453199916488
id(L2) =140453199464200
id(L1[0]) =140453199327944
id(L2[0]) =140453199464264
id(L1[1]) =140453198689984
id(L2[1]) =140453198689984

当深拷贝时,对拷贝的其中一个元素进行修改,不论该元素是不是可变的类型,其他的拷贝对象都不会随之改变。
注意!无论是浅拷贝还是深拷贝,对于不可变对象的元素,修改其中一个,另一个都不会随之改变,和深浅拷贝无关。

>>> L1 = [[1, 2, 3], 4]
>>> L2 = copy.deepcopy(L1)
>>> L2[0][1] = 999
>>> L2
[[1, 999, 3], 4]
>>> L1
[[1, 2, 3], 4]



>>> L1 = [[1, 2, 3], 4]
>>> L2 = copy.deepcopy(L1)
>>> L2[1] = 9999
>>> L2
[[1, 2, 3], 9999]
>>> L1
[[1, 2, 3], 4]

对于没有嵌套子对象的不可变对象,例如:整数对象、字符串对象和元组对象等,不会进行拷贝,也就是说,不会创建另一个对象,不论使用浅拷贝和深拷贝都不会进行拷贝

>>> i1 = 20
>>> i2 = int(i1)
>>> id(i1)
140090744170688
>>> id(i2)
140090744170688

>>> s1 = 'abc'

>>> s2 = copy.copy(s1)
>>> id(s1)
140090745589072
>>> id(s2)
140090745589072

>>> t1 = (1, 2, 3)      
>>> t2 = copy.copy(t1)
>>>
>>> id(t1)
140090599826560
>>> id(t2)
140090599826560

而对于嵌套了子对象的不可变对象,如果子对象是可变对象,则会进行拷贝

#!/usr/bin/python3

import copy

t1 = ([1, 2, 3], 4)
t2 = copy.deepcopy(t1)

print('id(t1) ={}'.format(id(t1)))
print('id(t2) ={}'.format(id(t2)))

print('id(t1[0]) ={}'.format(id(t1[0])))
print('id(t2[0]) ={}'.format(id(t2[0])))

print('id(t1[1]) ={}'.format(id(t1[1])))
print('id(t2[1]) ={}'.format(id(t2[1])))
[root@lyucan ~]# ./5.py
id(t1) =140616493770376
id(t2) =140616494039624
id(t1[0]) =140616493183624
id(t2[0]) =140616493988936
id(t1[1]) =140616492545728
id(t2[1]) =140616492545728

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com