Python的浅拷贝与深拷贝
定义:
- =号浅拷贝:在Python中对象的赋值其实就是对象的引用。copy了之后两个仍然是同一个东西。那么他们内部的元素自然也是一样的,对其中一个进行修改,另一个也会跟着变>
- copy()浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制.(copy了子对象)
- copy.deepcopy()深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。(子对象的子对象都copy了,很强大)
几个术语的解释:
- 变量:是一个系统表的元素,拥有指向对象的连接空间
- 对象:被分配的一块内存,存储其所代表的值
- 引用:是自动形成的从变量到对象的指针
- 注意:类型(int类型,long类型(python3已去除long类型,只剩下int类型的数据))属于对象,不是变量
- 不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数字
- 可变对象:可以修改的对象,包括列表、字典。
应用的范围:
- 切片可以应用于:列表、元组、字符串,但不能应用于字典。
- 深浅拷贝,既可应用序列(列表、元组、字符串),也可应用字典。
深浅拷贝的作用:
- 减少内存的使用。
- 以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。
对于不可变对象的深浅拷贝:
- 不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
- 一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
#先来简单的小示例
L = [1,2,3,[4,5,6],7] #=号copy
a = L #浅copy
b = L.copy() #深copy
import copy
c = copy.deepcopy(L) print(L)
print(a)
print(b)
print(c) L.remove(1)
L[3].remove(4) print(L)
print(a)
print(b)
print(c) #输出结果
[1, 2, 3, [4, 5, 6], 7]
[1, 2, 3, [4, 5, 6], 7]
[1, 2, 3, [4, 5, 6], 7]
[1, 2, 3, [4, 5, 6], 7] [1, 2, 3, [5, 6]] # L
[1, 2, 3, [5, 6]] # =号:指向型copy,都一样
[1, 2, 3, [5, 6], 7] # 浅copy,只copy到子对象
[1, 2, 3, [4, 5, 6], 7] # 深copy,子对象的子对象都copy,非常暴力
copy的内存地址详解:
import copy a=(1,2,3)
print("=====第一种=号浅拷贝=====")
b=a
print(a)
print(b)
print(id(a))
print(id(b))
print("=====另一种copy浅拷贝===")
b=copy.copy(a)
print(a)
print(b)
print(id(a))
print(id(b))
print("=====深拷贝=====")
b=copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))
# 结果如下:
=====浅拷贝=====
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
=====另一种浅拷贝===
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
=====深拷贝=====
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
对于可变对象深浅拷贝:
- =浅拷贝:值相等,地址相等
- copy浅拷贝:值相等,地址不相等
- deepcopy深拷贝:值相等,地址不相等
import copy a=[1,2,3]
print("=====第一种=号浅拷贝=====")
b=a
print(a)
print(b)
print(id(a))
print(id(b))
print("=====另一种copy浅拷贝===")
b=copy.copy(a)
print(a)
print(b)
print(id(a))
print(id(b))
print("=====深拷贝=====")
b=copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))
#结果如下:
=====浅拷贝=====
[1, 2, 3]
[1, 2, 3]
2007696321544
2007696321544
=====另一种copy浅拷贝===
[1, 2, 3]
[1, 2, 3]
2007696321544
2007695909960
=====深拷贝=====
[1, 2, 3]
[1, 2, 3]
2007696321544
2007696319560
'''注意'''
m = [1, 2, [3]]
n = m # =号浅拷贝
n[1] = 4
n[2][0] = 5
print(m)
#输出[1, 4, [5]] m = [1, 2, [3]]
n = m[:] # 效果等同copy浅拷贝
n[1] = 4
n[2][0] = 5
print(m)
#输出 [1, 2, [5]]
总结:
1,深浅拷贝都是对源对象的复制,占用不同的内存空间。
2,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
3,可变类型:
=浅拷贝: 值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,地址不相等
学习内容参考:
Python的浅拷贝与深拷贝的更多相关文章
- 深度解析:python之浅拷贝与深拷贝
深度解析python之浅拷贝与深拷贝 本文包括知识点: 1.copy与deepcopy 2.可变类型与不可变类型 1.copy与deepcopy 在日常python编码过程中,经常会遇见变量的赋值.这 ...
- python的浅拷贝和深拷贝
python对象有两种拷贝的形式:浅拷贝和深拷贝. 在<python核心编程>中看到对这两种拷贝的分析,觉得十分收益,所以记录在此. id()方法:id()方法可以查看某个对象的ID,类似 ...
- python:浅拷贝与深拷贝
1,“相等”与“相同” 我们先赋值三个变量a, b, c: a = [1, 2, [1, 2]] b = [1, 2, [1, 2]] c = a 判断一下‘相等’: a == b 返回 True ...
- python之浅拷贝和深拷贝
1.浅拷贝 1>赋值:从下面的例子我们可以看到赋值之后新变量的内存地址并没有发生任何变化,实际上python中的赋值操作不会开辟新的内存空间,它只是复制了新对象的引用,也就是说除了b这个名字以外 ...
- Python 列表浅拷贝与深拷贝
浅拷贝 shallow copy 和深拷贝 deep copy list.copy() 浅拷贝:复制此列表(只复制一层,不会复制深层对象) 等同于 L[:] 举例: 浅拷贝: a = [1.1, 2. ...
- Python中浅拷贝和深拷贝的区别总结与理解
单层浅拷贝 import copy a = 1 # 不可变数据类型 copy_a = copy.copy(a) print(id(a),id(copy_a)) # 内存地址相同 a = [1,2] # ...
- python中浅拷贝和深拷贝分析
首先,我们知道Python3中,有6个标准的数据类型,他们又分为可以变和不可变.不可变:Number(数字).String(字符串).Tuple(元组).可以变:List(列表).Dictionary ...
- python中浅拷贝和深拷贝的区别
浅拷贝 可变类型浅拷贝copy函数就是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象可变类型:a = [1, 2, 3] b = [11, 2 ...
- copy(python中的引用,浅拷贝,深拷贝)
#直接赋值 list = [1,2,['a','b'],'python'] #现将a等于list a = list print a [1,2,['a','b'],'python'] list.appe ...
随机推荐
- 运行RF测试案例,显示unable to open socket to "localhost:56505" error: [Errno 10061] 错误,且关闭RF卡死的解决办法
问题描述: 执行WEB ui测试案例后,执行请他的测试案例显示unable to open socket to "localhost:56505" error: [Errno 10 ...
- Ansible Playbook 使用条件判断语句
先介绍一下 gather_facts 参数,该参数用于指定在执行任务前,是否先执行 setup 模块获取主机相关信息,以便给后面的任务使用 [root@localhost ~]# ansible 19 ...
- Nginx 代理
如下,配置 Nginx 成为一台代理服务器 [root@localhost ~]$ cat /usr/local/nginx/conf/vhost/proxy.conf server { listen ...
- U3D调用7z解压文件
using UnityEngine; using System; using System.IO; using System.Diagnostics; public class Test : Mono ...
- TCPdump指定时间或者指定大小进行循环抓取报文
背景:我们用tcpdump工具循环抓取网卡上的报文,我们会遇到如下情况: 1. 抓取报文后隔指定的时间保存一次: 2. 抓取报文后达到指定的大小保存一次: 本文就这两种情况给出tcpdump的使用方法 ...
- CWnd与HWND的区别与转换
CWnd与HWND的区别与转换 2011-10-20 10:29:30| 分类: VC学习库|字号 订阅 一.区别HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是 ...
- Subversion权限详解
1 背景假设厦门央瞬公司是一家电子元器件设备供应商,其中有个ARM部门,专门负责ARM芯片的方案设计.销售,并在北京.上海各设立了一个办事处.对于工作日志,原先采用邮件方式发给经理,但是这种方式有 ...
- Win7/Win8/IIS7/IIS8配置ASP/ACCESS
1.在IIS信息服务管理器配置好站点后,配置ASP属性: a.IIS启用ASP 1.打开控制面板>>程序和功能>>“打开或关闭windows功能”,见下图 2.稍等片刻,出现一 ...
- 【大数据系列】MapReduce示例一年之内的最高气温
一.项目采用maven构建,如下为pom.xml中引入的jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xml ...
- Linux命令 dmesg:分析内核产生的信息
案例一 输出所有的内核开机时的信息 zh@zh:~$dmesg | more 案例二 查找开机的时候硬盘的相关信息