定义:

  • =号浅拷贝:在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. 8 -- 深入使用Spring -- 3...1 Resource实现类ClassPathResource

    8.3.1 Resource实现类------ClassPathResource : 访问类加载路径下的资源的实现类 2.访问类加载路径下的资源 ClassPathResource 用来访问类加载路径 ...

  2. PHP代码审计笔记--文件包含漏洞

    有限制的本地文件包含: <?php include($_GET['file'].".php"); ?> %00截断: ?file=C://Windows//win.in ...

  3. 使用 CSV 文件存储

    将爬取到的数据以 CSV 文件形式存储: import csv import requests req = requests.get("http://www.baidu.com/" ...

  4. Unity 蓝牙插件

    1.新建一个Unity5.6.2f1工程,导入正版Bluetooth LE for iOS tvOS and Android.unitypackage2.用JD-GUI反编译工具查看unityandr ...

  5. MVC的简单初步学习(2)

    今天似乎一切是正常的,我们的课依旧在进行着,但是恍惚脑海中并没有那样的平静,不知道在想些什么?而且今天是学习MVC的初步开始,我应该认真地学习才是正确的啊.但是我并不糊涂,今天是周一,也就是刚开始上课 ...

  6. [Z]修炼成C++高手必看的C++书单

    增添于网上的一些书单: C++/OPP/OOD系列: 层级一:语法/语意(C++) [Lippman2000] Essential C++ Essential C++,by Stanley B. Li ...

  7. Lua中的table构造式(table constructor)

    最简单的构造式就是一个空构造式{},用于创建一个空table. 构造式还可以用于初始化数组.例如,以下语句:days = {"Sunday", "Monday" ...

  8. 为JDK自带的jvisualvm安装Visual GC插件

    1.打开cmd,输入jvisualvm,回车: 2.点击工具——>插件; 3.访问网址:https://visualvm.github.io/pluginscenters.html,找到自己JD ...

  9. android模拟器与PC的端口映射

    一.概述 Android系统为实现通信将PC电脑IP设置为10.0.2.2,自身设置为127.0.0.1,而PC并没有为Android模拟器系统指定IP,所以PC电脑不能通过IP来直接访问Androi ...

  10. C++播放wav音乐和音效

    1.  #include <mmsystem.h>#pragma comment(lib,"winmm.lib")PlaySound(TEXT("c:\\te ...