Python列表的深复制和浅复制示例详解


Posted in Python onFebruary 12, 2021

一、深复制与浅复制

列表是Python中自带的一种数据结构,在使用列表时,拷贝操作不可避免,下面简单讨论一下列表的深复制(拷贝)与浅复制

首先看代码:

l1 = [5, 4, 3, 2, 1]
# 用两种方法实现对列表l1的拷贝
l2 = l1
l3 = l1[:]
print(l1) # [5, 4, 3, 2, 1]
print(l2) # [5, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]
 
#修改l1
l1[0] = 9
print(l1) # [9, 4, 3, 2, 1]
print(l2) # [9, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]

我们发现修改l1的第一个元素后,l2的第一个元素跟着改变,而l3并没有发生变化。Python内置函数id()可以返回元素的地址,那么我们使用这个函数来看一下三个列表的地址:

print(id(l1)) # 2927957162504
print(id(l2)) # 2927957162504
print(id(l3)) # 2927923243528

从结果来看,l1和l2地址是一样的,也就是说l1和l2指向的是同一块内存区域,显然,通过 l2 = l1 操作,l1和l2都成了指向同一块内存地址的“指针”,也就是说这个操作是为l1取了一个别名,也可以说l2是l1的一个引用。用一张图来解释:

Python列表的深复制和浅复制示例详解

那么修改l1也就是在修改l2:

Python列表的深复制和浅复制示例详解

接下来看一下创建l3的过程,l3 = l1[:] ,这是将l1进行切片,并将切片后的列表拷贝到l3所指向的内存区域,同样看图:

Python列表的深复制和浅复制示例详解

也就是说l1和l3指向不同的内存区域,那么修改l1并不会影响到l3:

Python列表的深复制和浅复制示例详解

通俗的来讲,像l2这种,拷贝出来的对象和原对象的地址相同,为浅复制,像l3这种,分配新的内存空间并拷贝原始内容的,拷贝出来的对象和原对象的地址不同,为深复制

二、复制列表内元素的浅复制

在复制列表中的所有元素的时候,进行浅复制

看一个比较有意思的东西,看代码:

l1 = [1,2,3,[1,3]]
l2 = l1[:]
l1[3][1] = 9
print(l1) # [1, 2, 3, [1, 9]]
print(l2) # [1, 2, 3, [1, 9]]

按照前面的理解,修改l1某个元素后,l2应该不会发生改变,可结果却与我们预想的结果大相径庭,于是,我们不得不思考一下l2深复制到底复制了什么东西。实际上列表其实可以理解为一个“指针”,l1[3]是一个列表元素,l2[3]也是一个列表元素,执行以下代码:

print(id(l2[3])) # 2014816956232
print(id(l1[3])) # 2014816956232

我们发现l1[3]和l2[3]指向的地址是一样的,也就是说在执行 l2 = l1[:] 的时候,将一个地址拷贝了,所以修改l1[3]相当于修改l2[3],所以才会出现上述结果,这更加说明了列表其实就是一个指向一片内存区域的“指针”。那么我们是不是可以说列表l2深复制l1,但是对列表中每个元素进行复制时进行的是浅复制呢?答案显而易见。

Python列表的深复制和浅复制示例详解

修改l1[3]中的元素:

Python列表的深复制和浅复制示例详解

三、copy()和deepcopy()

copy模块可以帮助我们实现对象的复制操作

列举一下其他的拷贝列表的方式:

l4 = l1 * 1
print(id(l4)) # 2927957916296
l5 = list(l1)
print(id(l5)) # 2927957767816
import copy
l6 = copy.copy(l1)
print(id(l6)) # 2927956854024
l7 = copy.deepcopy(l1)
print(id(l7)) # 2927958503368

我们可以看到,这几种拷贝方式所得到的的新对象与原对象的地址都不相同了,并没有按照字面意思(copy进行浅复制,deepcopy进行深复制),那么copy()和deepcopy()究竟有什么区别呢,继续看代码:

list1 = [1,2,3,[1,3]]
list2 = list1[:]
list3 = copy.copy(list1)
list4 = copy.deepcopy(list1)
list1[3][0] = 9
print(list1) # [1, 2, 3, [9, 3]]
print(list2) # [1, 2, 3, [9, 3]]
print(list3) # [1, 2, 3, [9, 3]]
print(list4) # [1, 2, 3, [1, 3]]
print(id(list1[3])) # 2927923172616
print(id(list2[3])) # 2927923172616
print(id(list3[3])) # 2927923172616
print(id(list4[3])) # 2927967190728

可以发现copy()和前面提到的用 [:] 进行拷贝没有本质上的区别,对列表中的每个元素进行复制时进行的是浅拷贝,而deepcopy()在复制列表中的每个元素的时候,进行的是深拷贝

Python列表的深复制和浅复制示例详解

Python列表的深复制和浅复制示例详解

总结

到此这篇关于Python列表的深复制和浅复制的文章就介绍到这了,更多相关Python列表深复制和浅复制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python创建只读属性对象的方法(ReadOnlyObject)
Feb 10 Python
python中的sort方法使用详解
Jul 25 Python
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
Apr 05 Python
python+requests+unittest API接口测试实例(详解)
Jun 10 Python
使用Python写一个量化股票提醒系统
Aug 22 Python
深度辨析Python的eval()与exec()的方法
Mar 26 Python
pip install python 快速安装模块的教程图解
Oct 08 Python
基于python3监控服务器状态进行邮件报警
Oct 19 Python
Python argparse模块应用实例解析
Nov 15 Python
如何在django中运行scrapy框架
Apr 22 Python
Python Matplotlib绘制条形图的全过程
Oct 24 Python
Python使用mitmproxy工具监控手机 下载手机小视频
Apr 18 Python
Python就将所有的英文单词首字母变成大写
Feb 12 #Python
详解Java中一维、二维数组在内存中的结构
Feb 11 #Python
SpringBoot首页设置解析(推荐)
Feb 11 #Python
使用Python爬取小姐姐图片(beautifulsoup法)
Feb 11 #Python
详解python日志输出使用配置文件格式
Feb 10 #Python
python 获取域名到期时间的方法步骤
Feb 10 #Python
Numpy ndarray 多维数组对象的使用
Feb 10 #Python
You might like
推荐文章系统(一)
2006/10/09 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
PHP的介绍以及优势详细分析
2019/09/05 PHP
PHP实现递归的三种方法
2020/07/04 PHP
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
jquery 单击li防止重复加载的实现代码
2010/12/24 Javascript
基于jquery的二级联动菜单实现代码
2011/04/25 Javascript
详解JS 比较两个Json对象的值是否相等的实例
2013/11/20 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
Jquery遍历select option和添加移除option的实现方法
2016/08/26 Javascript
不间断循环滚动效果的实例代码(必看篇)
2016/10/08 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
BootStrap整体框架之基础布局组件
2016/12/15 Javascript
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
2018/08/30 Javascript
vuejs+element UI点击编辑表格某一行时获取内容填入表单的示例
2018/10/31 Javascript
[02:11]2014DOTA2 TI专访VG战队Fenrir:队伍气氛良好
2014/07/11 DOTA
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
Django的URLconf中使用缺省视图参数的方法
2015/07/18 Python
python使用pil进行图像处理(等比例压缩、裁剪)实例代码
2017/12/11 Python
Python实现利用163邮箱远程关电脑脚本
2018/02/22 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
使用Python进行QQ批量登录的实例代码
2018/06/11 Python
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
楼面部长岗位职责范本
2014/02/14 职场文书
精彩的演讲稿开头
2014/05/08 职场文书
产品售后服务承诺书
2014/05/21 职场文书
服装设计专业求职信
2014/06/16 职场文书
大学生自荐信怎么写
2015/03/26 职场文书
2015年施工员工作总结范文
2015/04/20 职场文书
医院党建工作总结2015
2015/05/26 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
Logback 使用TurboFilter实现日志级别等内容的动态修改操作
2021/08/30 Java/Android