深拷贝和浅拷贝的区别 | 学习笔记

简介: 快速学习 深拷贝和浅拷贝的区别

开发者学堂课程【Python入门 2020年版深拷贝和浅拷贝的区别】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/639/detail/10307


深拷贝和浅拷贝的区别


内容介绍

一、浅拷贝回顾

二、深拷贝

三、网址推荐


一、浅拷贝回顾

首先我们定义一个 numsnums1 = nums 为等于时,表示相互关联的操作既不是深复制也不是浅复制,它仅仅是一个指向,是赋值操作。

1.赋值

#浅复制(拷贝)

nums = [12345]

nums1 = nums     #深拷贝/浅拷贝?都不是,只是一个赋值

2.  浅复制回顾

1)使用 Copy 方法

nums2 = nums.copy()表示浅复制,两者内容一致,但并不是同一个对象,无论修改其中的任何一个,都不会改变另一个的内容。

代码

nums = [12345]

nums2 = nums.copy()#浅复制。两个内容一模一样,但是不是同一个对象

2)使用 copy 模块

除此之外还可以使用 copy 模块,nums3 = copy.copy(nums)

来进行浅拷贝,和 nums2 = nums.copy() 两者的效果一致。

代码

import copy

nums = [12345]

#浅拷贝,两个内容一模一样,但是不是同一个对象

nums2 = nums.copy()

nums3 = copy.copy(nums)


二、深拷贝

深拷贝与浅拷贝不一样,只能使用 copy 模块实现,同时涉及到列表的嵌套。定义一个 words 列表并在其中添加嵌套。

1.引例

代码

import copy

#深拷贝,只能使用 copy 横块实现

words =[' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

#words1words 的浅拷贝

#浅拷贝认为只拷贝了一层

words1 = words.copy() //words 浅复制一份给 words1

words[0] = ‘你好   //word 中第一个元素变为‘你好’

print(words1) //输出 words1

words[2][0] = 1  //改变嵌套列表中的元素

print(words1)  //再次输出 words1

输出结果

[ ' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

[ ' hello', 'good ',[1200300]'yes', 'hi', 'ok' ]

思路解析:

Words 如今指向一块内存空间,此时又有一个 words1又复制了 words 指向内存空间中的所有元素,同时指向另一个空间。两者是不同的内存地址。此时将 words[0]改为你好word1[0]中的内容不会发生改变。

1.png

但如果改变 word 中嵌套的列表中的第一个元素 words[2][2]1,再次输出浅拷贝生成的 words1,会发现 word1中的对应的元素发生了改变。

因为浅拷贝被认为只拷贝了一层,所以 words 嵌套的内层列表并没有被拷贝,即列表中嵌套的如果是列表元素,不会再被拷贝。而是两者都指向该列表。

将内层列表的第一个元素100改为1时,words1是与 Word 共同指向嵌套部分的列表,所以输出的结果也变为1

1.png

2.深拷贝

深拷贝只可以用 copy 模块来实现,如要对 words 进行深拷贝写法为 words2 = copy.deepcopy(words)

代码

import copy

#深拷贝,只能使用 copy 横块实现

words = [ ' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

#深拷贝的 words2

words2 = copy.deepcopy(words)

words[0] = ‘你好

print(words2)

words[2][0] = 1

print(words2)

输出结果

[ ' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

[ ' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

words2和 word1不同,它是将 word 里全都拷贝过来。不管 word 里有任何嵌套列表都完全复制下来。

如将 words[0]改为你好或者是将 word 里嵌套的列表第一个元素进行修改,再输出 word2的结果都可以看出不会有任何的变化。实现了真正的两个独立的空间。

Tip:在元素遍历拿出来依次拷贝也不一定是深拷贝,需要通过遍历深度来判断。

1.png


三、网站推荐

同时我们可以登录 pythontutor.com 网站在其中的 Python Tutor 中去查看我们的代码的虚拟运行过程依次判断理解深拷贝。

首先在网站中输入代码,点击虚拟化执行代码。

网址:pythontutor.com

代码

import copy

words = [ ' hello', 'good '[100200300]'yes', 'hi', 'ok' ]

Word1 = words.copy()

words2 = copy.deepcopy(words)

words[2][0] = 1

1.png

1.png

虚拟执行过程:

可以看出,words 在指向其中嵌套的列表时,指向的是另一块内存。当执行第三行代码浅复制时,words1里的嵌套列表和 word 指向的是同一块内存,所以当改变嵌套列表元素时,会对应发生改变。

1.png

而当执行第四行的深复制代码时,word2中的嵌套列表并没有和 word 指向同一内存地址,而是完整的复制下 word 的内容,再全部指向另一块内存地址。

1.png

最后将 words[2][0]Word 中嵌套列表的第一个元素变为1,可以看到 words 和浅复制结果 word1指向的数据发生变化,而 words2并没发生变化。

1.png

相关文章
|
8月前
|
存储 人工智能 前端开发
深拷贝浅拷贝的区别?如何实现一个深拷贝?
深拷贝浅拷贝的区别?如何实现一个深拷贝?
115 0
|
3月前
|
存储 前端开发 JavaScript
浅拷贝和深拷贝的区别?
本文首发于微信公众号“前端徐徐”,介绍了JavaScript中浅拷贝和深拷贝的概念及其实现方法。文章首先解释了数据类型的基础,包括原始值和对象的区别,然后详细介绍了浅拷贝和深拷贝的定义、底层逻辑以及常见的实现方式,如 `Object.assign`、扩展运算符、`JSON.stringify` 和手动实现等。最后,通过对比浅拷贝和深拷贝的区别,帮助读者更好地理解和应用这两种拷贝方式。
133 0
浅拷贝和深拷贝的区别?
|
7月前
|
安全 Java
深拷贝和浅拷贝的区别
深拷贝和浅拷贝的区别
面试官:深拷贝与浅拷贝有啥区别?
面试官:深拷贝与浅拷贝有啥区别?
|
8月前
|
存储 Java Apache
【面试问题】深拷贝和浅拷贝的区别?
【1月更文挑战第27天】【面试问题】深拷贝和浅拷贝的区别?
|
JavaScript
一文弄懂浅拷贝和深拷贝
一文弄懂浅拷贝和深拷贝
58 0
|
存储 JavaScript 前端开发
深拷贝浅拷贝有什么区别?怎么实现深拷贝?
深拷贝浅拷贝有什么区别?怎么实现深拷贝?
106 0
|
JSON 数据格式
深拷贝和浅拷贝、及实现方式
深拷贝和浅拷贝、及实现方式
106 0
C++学习笔记_06 深拷贝和浅拷贝 2021-04-19
C++学习笔记_06 深拷贝和浅拷贝 2021-04-19
|
C++
C++类与对象中深拷贝与浅拷贝
C++类与对象中深拷贝与浅拷贝
71 0