定义:

  • =号浅拷贝:在Python中对象的赋值其实就是对象的引用。copy了之后两个仍然是同一个东西。那么他们内部的元素自然也是一样的,对其中一个进行修改,另一个也会跟着变>
  • copy()浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制.(copy了子对象)
  • copy.deepcopy()深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。(子对象的子对象都copy了,很强大)

几个术语的解释:

  1. 变量:是一个系统表的元素,拥有指向对象的连接空间
  2. 对象:被分配的一块内存,存储其所代表的值
  3. 引用:是自动形成的从变量到对象的指针
  4. 注意:类型(int类型,long类型(python3已去除long类型,只剩下int类型的数据))属于对象,不是变量
  5. 不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数字
  6. 可变对象:可以修改的对象,包括列表、字典。

应用的范围:

  1. 切片可以应用于:列表、元组、字符串,但不能应用于字典。
  2. 深浅拷贝,既可应用序列(列表、元组、字符串),也可应用字典。

深浅拷贝的作用:

  1. 减少内存的使用。
  2. 以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。

对于不可变对象的深浅拷贝:

  • 不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看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的浅拷贝与深拷贝的更多相关文章

  1. 深度解析:python之浅拷贝与深拷贝

    深度解析python之浅拷贝与深拷贝 本文包括知识点: 1.copy与deepcopy 2.可变类型与不可变类型 1.copy与deepcopy 在日常python编码过程中,经常会遇见变量的赋值.这 ...

  2. python的浅拷贝和深拷贝

    python对象有两种拷贝的形式:浅拷贝和深拷贝. 在<python核心编程>中看到对这两种拷贝的分析,觉得十分收益,所以记录在此. id()方法:id()方法可以查看某个对象的ID,类似 ...

  3. python:浅拷贝与深拷贝

    1,“相等”与“相同” 我们先赋值三个变量a, b, c: a = [1, 2, [1, 2]] b = [1, 2, [1, 2]] c = a 判断一下‘相等’: a == b  返回 True ...

  4. python之浅拷贝和深拷贝

    1.浅拷贝 1>赋值:从下面的例子我们可以看到赋值之后新变量的内存地址并没有发生任何变化,实际上python中的赋值操作不会开辟新的内存空间,它只是复制了新对象的引用,也就是说除了b这个名字以外 ...

  5. Python 列表浅拷贝与深拷贝

    浅拷贝 shallow copy 和深拷贝 deep copy list.copy() 浅拷贝:复制此列表(只复制一层,不会复制深层对象) 等同于 L[:] 举例: 浅拷贝: a = [1.1, 2. ...

  6. Python中浅拷贝和深拷贝的区别总结与理解

    单层浅拷贝 import copy a = 1 # 不可变数据类型 copy_a = copy.copy(a) print(id(a),id(copy_a)) # 内存地址相同 a = [1,2] # ...

  7. python中浅拷贝和深拷贝分析

    首先,我们知道Python3中,有6个标准的数据类型,他们又分为可以变和不可变.不可变:Number(数字).String(字符串).Tuple(元组).可以变:List(列表).Dictionary ...

  8. python中浅拷贝和深拷贝的区别

    浅拷贝 可变类型浅拷贝copy函数就是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象可变类型:a = [1, 2, 3] b = [11, 2 ...

  9. copy(python中的引用,浅拷贝,深拷贝)

    #直接赋值 list = [1,2,['a','b'],'python'] #现将a等于list a = list print a [1,2,['a','b'],'python'] list.appe ...

随机推荐

  1. ios开发之--两次模态弹出后,怎么返回最上层的页面

    解决方法如下: self.presentingViewController.view.alpha = ;[self.presentingViewController.presentingViewCon ...

  2. 在eclipse中查看android源代码

    自己写了一个类MainAcvitivity extends Activity, 按F12(我把转到定义改成了F12的快捷键),转到Activity的定义,弹出下面这样的界面 就是说没有找到androi ...

  3. spring + Mybatis + pageHelper + druid 整合源码分享

    springMvc + spring + Mybatis + pageHelper + druid 整合 spring 和druid整合,spring 整合druid spring 和Mybatis  ...

  4. ZTree id值太大,ZTree没有生成树,ZTree的id值过大

     ZTree id值太大,ZTree没有生成树,ZTree的id值过大 >>>>>>>>>>>>>>>> ...

  5. 【代码审计】QYKCMS_v4.3.2 任意文件删除漏洞分析

      0x00 环境准备 QYKCMS官网:http://www.qykcms.com/ 网站源码版本:QYKCMS_v4.3.2(企业站主题) 程序源码下载:http://bbs.qingyunke. ...

  6. Nginx 访问日志

    配置访问日志: [root@localhost ~]$ cat /usr/local/nginx/conf/nginx.conf http { log_format main '$remote_add ...

  7. Android 监听apk安装替换卸载广播

    首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程 ...

  8. 《C++ Primer Plus》16.3 标准模板库 学习笔记

    STL提供了一组表示容器.迭代其.函数对象和算法的模板.容器是一个与数组类似的单元,可以存储若干个值.STL容器是同质的,即存储的值的类型相同:算法是完成特定任务(如对数组进行排序或在链表中查找特定值 ...

  9. rabbitMQ常用的命令

    rabbitMQ常用的命令 启动监控管理器:rabbitmq-plugins enable rabbitmq_management 关闭监控管理器:rabbitmq-plugins disable r ...

  10. 【IE兼容问题】记一次Manifest因为jquery版本不同导致的兼容问题解决方案X-UA-Compatible

    最近在调试一个jquery插件Manifest 测试过程中发现IE一直不能完全展示这个插件,只显示了一个textbox文本框 IE下的bug的效果图 其他浏览器正常的效果图 跟踪原因,IE下jquer ...