一、赋值、浅拷贝与深拷贝

  • 直接赋值:其实就是对象的引用(别名)。

  • 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。

  • 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

赋值实例:

# 赋值运算 变量指向同一个内存地址
l1 = [1,2,3]
l2 = l1
l3 = l2
l1.append(666)
print(l1,l2,l3)
print(id(l1),id(l2),id(l3))
# 运行结果:
# [1, 2, 3, 666] [1, 2, 3, 666] [1, 2, 3, 666]
# 1543171498568 1543171498568 1543171498568  赋值运算 变量指向同一个内存地址
赋值实例: 赋值运算 变量指向同一个内存地址

浅拷贝实例:

# copy一个新列表(dict),列表在内存中是新的,但是列表里面的元素,完全沿用之前的元素。
l1 = [1, 2,{'alex':23},4,[22,33]]
l2 = l1.copy()
l1[-1].append(44)
l1[2]['taibai'] = 18
l2[-1].append(55)
l2[2]['egon'] = 36
print(id(l1),id(l2))  #1583337071240 1583337553800
print(id(l1[-1]),id(l2[-1])) #1583337071176 1583337071176
print(l1,l2)#[1, 2, {'alex': 23, 'taibai': 18, 'egon': 36}, 4, [22, 33, 44, 55]]        [1, 2, {'alex': 23, 'taibai': 18, 'egon': 36}, 4, [22, 33, 44, 55]]

l1[0] = 2
l1[-1].append(88)
l2[-1].append(99)
l1.append(666)
l2.append(999)
print(l1,l2)#[2, 2, {'alex': 23, 'taibai': 18, 'egon': 36}, 4, [22, 33, 44, 55, 88, 99], 666] [1, 2, {'alex': 23, 'taibai': 18, 'egon': 36}, 4, [22, 33, 44, 55, 88, 99], 999]
print(id(l1[0]),id(l2[0])) #140721386935360 140721386935328
print(id(l1),id(l2))#1866099286664 1866099769224
实例一
l1 = [1, 2, 3, [22, 33]]
l2 = l1[:] # 切片 是 浅copy
l1[-1].append(666)
print(id(l1),id(l2)) #不是赋值关系  2304312369800 2304312852040
print(l1,l2)  #[1, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33, 666]]
列表切片属于浅拷贝
x = ['lily', '20', 'hr',['a']]
y = x
x[0] = 'lucy'
z = list(x)  #列表实例化对象也是前拷贝
x[0] = 'lilei'
x[-1].append('b')
z[-1].append('c')
print(x,y,z)#['lilei', '20', 'hr', ['a', 'b', 'c']] ['lilei', '20', 'hr', ['a', 'b', 'c']] ['lucy', '20', 'hr', ['a', 'b', 'c']]
print(id(x),id(y),id(z))#1744470303368 1744470303368 1744502045704
列表实例化对象也是前拷贝

 图片解析赋值、浅拷贝和深拷贝原理

1、b = a: 赋值引用,a 和 b 都指向同一个对象。

2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。

3、b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。

深拷贝实例:深度拷贝需要引入 copy 模块

import copy
# 总结:深copy则会在内存中开辟新空间,将原列表以及列表里面的可变的数据类型重新创建一份,
# 不可变的数据类型则沿用之前的。
l1 = [1, 2, 3, [22, 33]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2))
print(id(l1[0]),id(l2[0]))
print(id(l1[-1]),id(l2[-1]))
l1[0] = 2
l1[-1].append(666)
print(l1,l2)
# 运行结果:
# 2522273468936 2522273389832
# 140732471497760 140732471497760
# 2522273604680 2522273605000
# [2, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33]]
#
# 小知识点:
# id 测试对象的内存地址
# == 比较 比较两边的数值是否相等
# print(2 == 2)
# is 判断 判断的两边对象的内存地址是否是同一个
深拷贝实例 内存地址比较 id