深浅拷贝

Posted zhangchaocoming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深浅拷贝相关的知识,希望对你有一定的参考价值。

copy 模块

1.拷贝(赋值)

1). x为不可变数据类型

x = 10
y = x
print(x,y)
print(id(x),id(y))
x += 1
print(x,y)
print(id(x),id(y))
'''
10 10
1828744960 1828744960
11 10
1828744992 1828744960
'''

? 结论:y为x的拷贝对象,x为不可变数据类型,x变化y 不变;

2). x为可变数据类型

x = [1,2,3]
y = x
print(x,y)
print(id(x),id(y))
x += [4]
print(x,y)
print(id(x),id(y))
'''
[1, 2, 3] [1, 2, 3]
167373768 167373768
[1, 2, 3, 4] [1, 2, 3, 4]
167373768 167373768
'''

? 结论:当y为x的拷贝对象,x为可变数据类型,x变化y也变;

3). 可变数据类型(比如列表)内,既有不可变元素,又有容器类型可变元素(比如列表)

# 没添加新元素前
l1 = [1,2,3,[4,5]]
l2=l1
print('id(l1):',id(l1))
print('id(l2):',id(l2))
print(id(l1[0]))
print(id(l1[1]))
print(id(l1[2]))
print(id(l1[3]))
print(id(l1[3][0]))
print(id(l1[3][1]))
print('='*50)
print(id(l2[0]))
print(id(l2[1]))
print(id(l2[2]))
print(id(l2[3]))
print(id(l2[3][0]))
print(id(l2[3][1]))
'''
1843162592
1843162624
1843162656
167373768
1843162688
1843162720
==================================================
1843162592
1843162624
1843162656
167373768
1843162688
1843162720
'''
# 添加新元素后
# l1中添加一个不可变类型元素l1.append(4);在l1[3]中添加一个不可变元素l1[3].append(6);
l1 = [1,2,3,[4,5]]
l2=l1
l1.append(4)
l1[3].append(6)

print('id(l1):',id(l1))
print('id(l1[3]):',id(l1[3]))
print('l1:',l1)

print('='*50)

print('id(l2):',id(l2))
print('id(l2[3]):',id(l2[3]))
print('l2:',l2)
'''
id(l1): 167761224
id(l1[3]): 167718088
l1: [1, 2, 3, [4, 5, 6], 4]
==================================================
id(l2): 167761224
id(l2[3]): 167718088
l2: [1, 2, 3, [4, 5, 6], 4]
'''

? 结论: 当l2为l1的拷贝对象,l1内部的不可变数据变化,lt2变;l1内部的可变数据变化,l2也变(*****)

2.浅拷贝

# 没添加新元素前
import copy
l1 = [1,2,3,[4,5]]
l2 = copy.copy(l1) 
print('id(l1):',id(l1))
print(id(l1[0]))
print(id(l1[1]))
print(id(l1[2]))
print(id(l1[3]))
print(id(l1[3][0]))
print(id(l1[3][1]))
print('='*30)
print('id(l2):',id(l2))
print(id(l2[0]))
print(id(l2[1]))
print(id(l2[2]))
print(id(l2[3]))
print(id(l2[3][0]))
print(id(l2[3][1]))
print('l2:',l2)

'''
id(l1): 167761224
1681026528
1681026560
1681026592
id(l1[3]:) 167718088
1681026624
1681026656
==============================
id(l2): 167778760
1681026528
1681026560
1681026592
id(l2[3]:) 167718088
1681026624
1681026656
l2: [1, 2, 3, [4, 5]]
'''
# 添加新元素后
import copy
l1 = [1,2,3,[4,5]]
l2 = copy.copy(l1) 
l1.append(4)
l1[3].append(6)

print('l1:',l1)
print('id(l1):',id(l1))
print('id(l1[3]):',id(l1[3]))

print('='*30)
print('l2:',l2)
print('id(l2):',id(l2))
print('id(l2[3]):',id(l2[3]))

'''
l1: [1, 2, 3, [4, 5, 6], 4]
id(l1): 167761224
id(l1[3]): 167718088  # l2为l1的浅拷贝对象,l1中的容器类型的内存地址与l2中的相同。
==============================
l2: [1, 2, 3, [4, 5, 6]]
id(l2): 167778760
id(l2[3]): 167718088
'''

? 结论:当l2为l1的浅拷贝对象时,l1内部的不可变元素变化,l2不变;l1内部的可变元素变化,l2也变(*********)

3.深拷贝

# 没添加新元素前
import copy

l1 = [1,2,3,[4,5]]
l2 = copy.deepcopy(l1) 

print('id(l1):',id(l1))
print(id(l1[0]))
print(id(l1[1]))
print(id(l1[2]))
print('id(l1[3]:',id(l1[3]))
print(id(l1[3][0]))
print(id(l1[3][1]))
print('='*30)
print('id(l2):',id(l2))
print(id(l2[0]))
print(id(l2[1]))
print(id(l2[2]))
print('id(l2[3]:',id(l2[3]))
print(id(l2[3][0]))
print(id(l2[3][1]))
print('l2:',l2)

'''
id(l1): 167761224
2012048864
2012048896
2012048928
id(l1[3]: 167718088
2012048960
2012048992
==============================
id(l2): 167778760
2012048864
2012048896
2012048928
id(l2[3]: 167778376
2012048960
2012048992
l2: [1, 2, 3, [4, 5]]
'''
# l2位l1的深拷贝对象,容器l2和容器l2内部的容器所对应的内存地址与l1都不同,相当于又重新开辟了新的内存空间
# 添加新元素后
import copy
l1 = [1,2,3,[4,5]]
l2 = copy.deepcopy(l1) 
l1.append(4)
l1[3].append(6)

print('l1:',l1)
print('id(l1):',id(l1))
print('id(l1[3]):',id(l1[3]))

print('='*30)
print('l2:',l2)
print('id(l2):',id(l2))
print('id(l2[3]):',id(l2[3]))

'''
l1: [1, 2, 3, [4, 5, 6], 4]
id(l1): 167761224
id(l1[3]): 167718088
==============================
l2: [1, 2, 3, [4, 5]]
id(l2): 167778760
id(l2[3]): 167778376
'''
# l1容器内及l1内部容器内添加新元素,l2容器及其内部容器内并没有添加新元素;

? 结论: 当l2是l1的深拷贝对象时,l1内部的不可变类型变化,l2不变;l1内部的可变类型变化,l2不变(*****)

4.拷贝现象总结及画图解释

技术图片

总结:

? 拷贝:当l2为l1的拷贝对象,l1内部的可变或不可变数据变化,lt2变;(*****)

? 浅拷贝: 当l2为l1的浅拷贝对象时,l1内部的不可变元素变化,l2不变;l1内部的可变元素变化,l2变(*********)

? 深拷贝:当l2是l1的深拷贝对象时,l1内部的不可变类型变化,l2不变;l1内部的可变类型变化,lt2不变(*****)

以上是关于深浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

《关于JavaScript的深浅拷贝》

python--is/id==,集合,深浅拷贝

python深浅拷贝

我要学python之深浅拷贝原理

Python高级语法-深浅拷贝-总结(4.2.1)

Python 的深浅拷贝 终于明白了