python(深浅拷贝)

1、深浅拷贝理解

  • 深拷贝和浅拷贝需要注意的地方就是可变元素的拷贝:
    • 在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的,也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的,但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别。
  • 也可以这样理解:
    • 深拷贝就是完全跟以前就没有任何关系了,原来的对象怎么改都不会影响当前对象  
    • 浅拷贝,原对象的 list 元素改变的话会改变当前对象,如果当前对象中 list 元素改变了,也同样会影响原对象。  
    • 浅拷贝就是藕断丝连  
    • 深拷贝就是离婚了  

2、深拷贝 

  • 克隆一份,修改拷贝后的对象中的可变元素不对原对象内容产生影响
  • copy 模块中的 deepcopy()
import copy

list1 = [["北京多测师","成都多测师"],"上海多测师","深圳多测师","广州多测师"]
list2 = copy.deepcopy(list1)   # 进行深拷贝
# 打印 list1 和 list2 两个列表的内存地址 => 结果不一样
print(id(list1))    # 3132367069640
print(id(list2))    # 3132368415752
# 打印 list1 和 list2 两个列表中的子列表的内存地址 => 结果不一样
print(id(list1[0]))     # 3132368414728
print(id(list2[0]))     # 3132368415688
# 修改拷贝后的 list2 中的可变数据类型的数据
list2[0][0] = "武汉多测师"
# 结果 list2 列表修改了,但是不影响 list1 列表数据
print(list2)    # [['武汉多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']
print(list1)    # [['北京多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']

3、浅拷贝

  • 修改拷贝后的内容中的可变数据,原对象内容随之修改
  • 列表函数 copy() 进行浅拷贝
list1 = [["北京多测师","成都多测师"],"上海多测师","深圳多测师","广州多测师"]
list2 = list1.copy()   # 进行浅拷贝
# 打印 list1 和 list2 两个列表的内存地址 => 结果不一样
print(id(list1))    # 2105959073864
print(id(list2))    # 2105989035464
# 打印 list1 和 list2 两个列表中的子列表的内存地址 => 结果一样
print(id(list1[0]))     # 2105989035592
print(id(list2[0]))     # 2105989035592
# 修改拷贝后的 list2 中的可变数据类型的数据
list2[0][0] = "武汉多测师"
# 结果 list2 列表修改了,list1 列表数据也修改了
print(list2)    # [['武汉多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']
print(list1)    # [['武汉多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']
  • copy 模块中的 copy()
import copy

list1 = [["北京多测师","成都多测师"],"上海多测师","深圳多测师","广州多测师"]
list2 = copy.copy(list1)   # 进行浅拷贝
# 打印 list1 和 list2 两个列表的内存地址 => 结果不一样
print(id(list1))    # 2129586840008
print(id(list2))    # 2129588186120
# 打印 list1 和 list2 两个列表中的子列表的内存地址 => 结果一样
print(id(list1[0]))     # 2129588185096
print(id(list2[0]))     # 2129588185096
# 修改拷贝后的 list2 中的可变数据类型的数据
list2[0][0] = "武汉多测师"
# 结果 list2 列表修改了,list1 列表数据也修改了
print(list2)    # [['武汉多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']
print(list1)    # [['武汉多测师', '成都多测师'], '上海多测师', '深圳多测师', '广州多测师']

4、实例讲解

# 现有老公张三有额度为 200000 元的信用卡,卡号为:20200520,已使用的额度:15000
# 现需要实现张三的老婆 Andy 也需要绑定这张信用卡进行付款

zs_card = ["张三",20200520,[200000,15000]]    # 张三名下的信用卡

ad_card = zs_card.copy()    # 妻子 Andy 账户也开了一张绑定张三信用卡的信用卡,且修改姓名和卡号
ad_card[0] = "Andy"
ad_card[1] = 20200521
print(ad_card)   # 打印出 Andy 的信用卡信息 ['Andy', 20200521, [200000, 15000]]

zs_card[2][1] += 2000   # 此时张三使用了信用卡且刷了 2000 元

print(ad_card)  # 此时 Andy 的信用卡额度也随之变化

# 运行结果如下
['Andy', 20200521, [200000, 15000]]
['Andy', 20200521, [200000, 17000]]    # 张三刷卡后,Andy 所持的信用卡已使用的额度随之增长

 

posted @ 2020-05-03 19:21  一个老宅男  阅读(1004)  评论(1编辑  收藏  举报