美文网首页Python全栈
深拷贝与浅拷贝

深拷贝与浅拷贝

作者: InsaneLoafer | 来源:发表于2022-03-18 16:31 被阅读0次

前提

存在一个列表:list1=['egon', 'lxx', [1,2]]

list1的内存图示:

image

列表赋值操作,二者不可分割

list2=list1,此操作使二者不可分割,一个改动另一个也改动,因为内存地址完全相同,指向的值也相同

['egon', 'lxx', [1,2]
list2 = list1
list1[0] = 'EGON'
print(list2)
>>>> 
    ['EGON', 'lxx', [1,2]
image

此操作不是列表的拷贝,只是赋值操作。

需求:

  1. 拷贝一下原列表,产生一个新列表
  2. 想让两个列表完全独立开(针对的是列表的修改操作,而不是读操作)

如何拷贝列表

一、浅拷贝copy

  • 拷贝完成后的列表完全相同
list3 = list1.copy()
print(id(list1[0], id(list1[1]), id(list1[2]))
print(id(list3[0], id(list3[1]), id(list3[2]))
>>>>
2031475499056 2031475460976 2031475448448
2031475499056 2031475460976 2031475448448
  • 修改list1的值,发现针对不可变类型的数值没变,但是针对可变类型的数值跟着一起变化

实验一:

list1[0] = 'EGON'
list1[1] = 'LXX'
list1[2] = 123  # 将第三个列表整体修改为不可变类型

print(list1)
print(list3)

>>>>
    ['EGON', 'LXX', 123]
    ['egon', 'lxx', [1, 2]]  # list3没有改变

实验二:

list1[0] = 'EGON'
list1[1] = 'LXX'
list1[2][0] = 111  # 将第三个列表的每个可变类型进行修改
list1[2][1] = 222  # 将第三个列表的每个可变类型进行修改

print(list1)
print(list3)
>>>>
    ['EGON', 'LXX', [111, 222]]
    ['egon', 'lxx', [111, 222]]  # list3的第三个列表里的值跟着变化
image

浅拷贝概念:

把原列表的第一层内存地址不加区分完全copy一份给新列表。

如果原列表全是不可变类型,修改没有问题;但是如果原列表有可变类型,修改可变类型的值将会同步修改新列表。

二、深拷贝deepcopy

综合实验1与实验2得出,要想copy得到的新列表与原列表的改操作完全独立开,必须有一种可以****区分开可变类型和不可变类型的copy机制****,这就是深拷贝。

  • 针对可变类型,深拷贝会copy一个内存地址不同的数据
import copy

list1 = ['egon', 'lxx', [1, 2]]
list3 =copy.deepcopy(list1)
print(id(list1))
print(id(list3))

#         不可变        不可变          可变
print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list3[0]), id(list3[1]), id(list3[2]))
>>>>
    2396863448128
    2396866008128
    2396863143984 2396863314352 2396865996608
    2396863143984 2396863314352 2396863379712
  • 可变类型中的值内存地址相同
print(id(list1[2][0]), id(list1[2][1]))
print(id(list3[2][0]), id(list3[2][1]))
>>>>
3075299764528 3075299764560
3075299764528 3075299764560
image
  • 修改操作,深拷贝的列表即使是可变数据类型也不会收到影响
list1[0] = 'EGON'
list1[1] = 'LXX'
list1[2][0] = 111
list1[2][1] = 222

print(list1)
print(list3)
>>>>
['EGON', 'LXX', [111, 222]]
['egon', 'lxx', [1, 2]]
image

总结

浅拷贝:只针对列表的第一层进行拷贝,会将数据的第一层所有数据的内存地址进行拷贝,导致如果是可变类型数据会与原列表分割不开,原列表修改可变数据后会同步修改浅拷贝的列表对应的数据。

深拷贝:会对可变和不可变类型加以区分,针对可变数据类型拷贝出来的内存地址不相同,这样原列表即使修改了可变数据类型的数据也不会影响深拷贝后的列表。

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • 认识js下的浅拷贝与深拷贝

    浅拷贝与深拷贝 首先深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象的。简单来说,浅拷贝只拷贝一...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解iOS ...

  • 深拷贝和浅拷贝

    干货!深拷贝和浅拷贝的区别 深拷贝才是拷贝,浅拷贝就是Retain Copy与Retain的区别 Copy: 根据...

  • js浅拷贝、深拷贝

    前言 本文主要简单讲一下什么是浅拷贝、什么是深拷贝、深拷贝与浅拷贝的区别,以及怎么进行深拷贝和怎么进行浅拷贝。 一...

  • iOS 图文并茂的带你了解深拷贝与浅拷贝

    iOS 图文并茂的带你了解深拷贝与浅拷贝 iOS 图文并茂的带你了解深拷贝与浅拷贝

  • 深拷贝和浅拷贝

    1: iOS开发 深拷贝与浅拷贝 2: iOS 浅谈:深.浅拷贝与copy.strong 3: iOS开发——深...

  • [C++之旅] 15 深拷贝与浅拷贝

    [C++之旅] 15 深拷贝与浅拷贝 拷贝构造函数分为深拷贝和浅拷贝两种方式 浅拷贝只是将被拷贝的对象的成员直接赋...

  • 深拷贝VS浅拷贝

    深拷贝VS浅拷贝 本文主要对深拷贝&浅拷贝的解释及实现做一下简单记录。 之所以会有深拷贝与浅拷贝之分,是因为不同数...

网友评论

    本文标题:深拷贝与浅拷贝

    本文链接:https://www.haomeiwen.com/subject/yltwdrtx.html