深浅copy详解

深浅copy

前言:深浅copy会在很多面试题中都会问到,所以搞懂它们之间的区别是很有必要性的

本篇中的所有图解只是帮助大家进行理解

1. 可变与不可变数据类型

  • 可变数据类型:列表,字典,集合
  • 不可变数据类型:字符串,元组,数字

2. 浅拷贝
先拿图说话:图中的123123等数值假设为内存地址
在这里插入图片描述
在图中我们可以明显的看到浅拷贝过后,两个列表l1和l2的引用还是指的是同一个值,所以当我们更改这两个列表的任何可变数据类型时,另一个列表的值一定会跟着变化。

注意:这里我强调了更改的值必须是可变数据类型时,另一个列表的值才会跟着变化

代码证明:

  1. 更改嵌套列表的值
    l1 = [1, '小明', [1, '小红', 3]]
    l2 = l1.copy()   # 或者导入copy模块,l2 = copy.copy(l1)
    
    l1[-1][1] = '李华'
    print(id(l1))
    print(id(l2))
    
    print(id(l1[-1]))
    print(id(l2[-1]))
    print(l1)
    print(l2)
    
    # 输出:
    	400648025856   # 两个列表的内存地址不同代表另外给l2开辟一块新的空间	
    	400648025984
    	
    	117588479680    # 证明两个列表中的可变数据类型为同一个
    	117588479680
    	[1, '小明', [1, '李华', 3]]   # 对l1的嵌套列表进行了更改,l2也跟着变化,代表了两个列表引用的值是同一个
    	[1, '小明', [1, '李华', 3]]
    
  2. 更改列表中不可变数据类型的值
    l1 = [1, '小明', [1, '小红', 3]]
    l2 = l1.copy()
    
    l1[1] = '小张'
    print(l1)
    print(l2)
    
    输出:
    	[1, '小张', [1, '小红', 3]]  # 两个列表的值竟然不一样了
    	[1, '小明', [1, '小红', 3]]
    
    这时肯定就有人疑惑了,不是说两个列表都是引用的同一个值么,为什么l1的值更改了,而l2的值没有更改呢?原因是这样的,我们其实更改的值不是真实存储的值,而且更改了l1列表中内存地址为456456的引用,将456456指向了另一个值 ‘小张’,主要原因就是字符串它是不可变的数据类型,所以我们更改不了字符串的值。
    在这里插入图片描述
    总结:根据以上实验,我们可以这样理解,浅拷贝就是两个列表中的可变数据类型仍是同一个。更改任何一个列表中的可变数据,另一个列表的值也会跟着变化

3. 深拷贝
和字面意思一样,完全复制一份新的出来,与原列表再无任何联系。这里就不再画图。

我们首先得借助内置的copy模块

  1. 更改嵌套的可变数据类型,这里我们以字典进行演练。注意与列表一样也是可变数据类型。

    import copy
    l1 = [1, '小明', {'name': '小张'}]
    l2 = copy.deepcopy(l1)
    
    l1[-1]['name'] = '小花'
    print(id(l1))
    print(id(l2))
    print(l1)
    print(l2)
    
    # 输出:
    	705449836608   # 两个列表的内存地址仍不一样,代表为拷贝的l2新开辟了一块空间
    	705449810432
    	[1, '小明', {'name': '小花'}]   # 更改了l1中的可变数据类型字典的值,l1变化了,而l2没有变化
    	[1, '小明', {'name': '小张'}]
    

    这就证明了深拷贝后的列表已经与原先的列表无关了。

  2. 补充:上面我们说的深拷贝后的列表与原列表没有任何联系了,其实并不然,python解释器做了优化的,两个列表中的不可变数据类型指向仍为同一个值,但是可变数据类型就是各自的互不影响。
    在这里插入图片描述

4. 思考
此时是深copy还是浅copy

l1 = [1, 2, '小红', {'name': '夏天'}]
l2 = l1[:]

l1[-1]['name'] = '冬天'
print(l1)
print(l2)

答案是:浅拷贝

结语:深拷贝与浅拷贝在面试时会问,所以还是得分清两者之间的区别,本章知识点到这里结束。觉得博主讲的还算不错的可以点个赞,你们的鼓励是我最大的动力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章