Python基础之赋值,浅拷贝,深拷贝的区别


Posted in Python onApril 30, 2021

一、赋值

不会开辟新的内存空间,只是复制了新对象的引用。所以当一个数据发生变化时,另外一个数据也会随之改变。

二、 浅拷贝

创建新对象,其内容是对原对象的引用。浅拷贝之所以称为浅拷贝,是因为它仅仅只拷贝了第一层,即只拷贝了最外层的对象本身,内部的元素都只是拷贝了一个引用而已,即内部元素如果被修改,则另外一个数据也会发生变化。

浅拷贝的三种形式:

A = [1, 2, 3, 4]
  • 切片操作
# 第1种
B = A[:]
# 第2种
B = [a for a in A]
  • 工厂函数
B = list(A)
  • copy函数
B = copy.copy(A)

浅拷贝要分两种情况进行讨论:

1)当浅拷贝的值是不可变对象(例如字符串、元组、数值类型)时,和赋值情况一样,对象的内存地址(id())与浅拷贝原来的值一致。

2)当浅拷贝的值是可变对象(例如列表、字典、集合等)时,也需要分两种情况讨论:

首先,原来值的内存地址与拷贝后的内存地址不同。

  • 当要拷贝的对象里面,没有可变的子对象时,原来值(拷贝值)的改变并不会影响拷贝值(原来值)。
  • 当要拷贝的对象里面,有可以改变的子对象时,改变该子对象,原来值和拷贝值之间会互相影响。

三、深拷贝

深拷贝拷贝出来的对象是一个全新的对象,和原来的对象没有任何的关联。改变原有对象不会影响新的拷贝对象。

四、例子

  • 不可变对象
import copy
# 不可变对象
# A = (1, 2, 'hello')   # 元组
# A = 1                 # 数值
A = 'hello'             # 字符串

print("********赋值********")
B = A
print(id(A))
print(id(B))
print(A)
print(B)

print("********浅拷贝********")
B = copy.copy(A)
print(id(A))
print(id(B))
print(A)
print(B)

print("********深拷贝********")
B = copy.deepcopy(A)
print(id(A))
print(id(B))
print(A)
print(B)

结果:

********赋值********
1894005658264
1894005658264
hello
hello
********浅拷贝********
1894005658264
1894005658264
hello
hello
********深拷贝********
1894005658264
1894005658264
hello
hello

  • 可变对象
import copy
# 可变对象
A = [1, 2, 3]

print("********赋值********")
B = A
print(id(A))
print(id(B))
print(A)
print(B)

print("********浅拷贝********")
B = copy.copy(A)
print(id(A))
print(id(B))
print(A)
print(B)

print("********深拷贝********")
B = copy.deepcopy(A)
print(id(A))
print(id(B))
print(A)
print(B)

结果:

********赋值********
1602694308360
1602694308360
[1, 2, 3]
[1, 2, 3]
********浅拷贝********
1602694308360
1602694308424
[1, 2, 3]
[1, 2, 3]
********深拷贝********
1602694308360
1602950316296
[1, 2, 3]
[1, 2, 3]

  • 可变对象修改外层
import copy
# 可变对象
A = [1, 2, 3, [11, 10, 20]]

# 可变对象的外层修改
B1 = A                   # 赋值
B2 = copy.copy(A)        # 浅拷贝
B3 = copy.deepcopy(A)    # 深拷贝
A.append(4)
print("********赋值********")

print(id(A))
print(id(B1))
print(A)
print(B1)

print("********浅拷贝********")
print(id(A))
print(id(B2))
print(A)
print(B2)

print("********深拷贝********")
print(id(A))
print(id(B3))
print(A)
print(B3)

结果:

********赋值********
2215309238856
2215309238856
[1, 2, 3, [11, 10, 20], 4]
[1, 2, 3, [11, 10, 20], 4]
********浅拷贝********
2215309238856
2215593496776
[1, 2, 3, [11, 10, 20], 4]
[1, 2, 3, [11, 10, 20]]
********深拷贝********
2215309238856
2215593518024
[1, 2, 3, [11, 10, 20], 4]
[1, 2, 3, [11, 10, 20]]

  • 可变对象修改内层
import copy
# 可变对象
A = [1, 2, 3, [11, 10, 20]]

# 可变对象的内层修改
B1 = A                   # 赋值
B2 = copy.copy(A)        # 浅拷贝
B3 = copy.deepcopy(A)    # 深拷贝
A[3].append(4)
print("********赋值********")

print(id(A))
print(id(B1))
print(A)
print(B1)

print("********浅拷贝********")
print(id(A))
print(id(B2))
print(A)
print(B2)

print("********深拷贝********")
print(id(A))
print(id(B3))
print(A)
print(B3)

结果

********赋值********
2288591069768
2288591069768
[1, 2, 3, [11, 10, 20, 4]]
[1, 2, 3, [11, 10, 20, 4]]
********浅拷贝********
2288591069768
2288847138760
[1, 2, 3, [11, 10, 20, 4]]
[1, 2, 3, [11, 10, 20, 4]]
********深拷贝********
2288591069768
2288847168264
[1, 2, 3, [11, 10, 20, 4]]
[1, 2, 3, [11, 10, 20]]

到此这篇关于Python基础之赋值,浅拷贝,深拷贝的区别的文章就介绍到这了,更多相关Python赋值 浅拷贝 深拷贝的区别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python写的一个文本编辑器
Jan 23 Python
在Python中使用HTMLParser解析HTML的教程
Apr 29 Python
Pandas:Series和DataFrame删除指定轴上数据的方法
Nov 10 Python
在python中使用requests 模拟浏览器发送请求数据的方法
Dec 26 Python
Python3获取电脑IP、主机名、Mac地址的方法示例
Apr 11 Python
简单了解django索引的相关知识
Jul 17 Python
一行Python代码过滤标点符号等特殊字符
Aug 12 Python
Python学习笔记之Zip和Enumerate用法实例分析
Aug 14 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
Dec 22 Python
Python map及filter函数使用方法解析
Aug 06 Python
Python字符串及文本模式方法详解
Sep 10 Python
Python通过递归函数输出嵌套列表元素
Oct 15 Python
python绘图subplots函数使用模板的示例代码
教你怎么用Python处理excel实现自动化办公
解决python绘图使用subplots出现标题重叠的问题
python数据库批量插入数据的实现(executemany的使用)
Apr 30 #Python
Python如何把不同类型数据的json序列化
Apr 30 #Python
python实现三次密码验证的示例
Django一小时写出账号密码管理系统
You might like
php根据年月获取季度的方法
2014/03/31 PHP
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
PHP7+Nginx的配置与安装教程详解
2016/05/10 PHP
thinkphp5.1 文件引入路径问题及注意事项
2018/06/13 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
PHP中用Trait封装单例模式的实现
2019/12/18 PHP
JavaScript中的其他对象
2008/01/16 Javascript
JS 非图片动态loading效果实现代码
2010/04/09 Javascript
jQuery 阴影插件代码分享
2012/01/09 Javascript
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
2014/03/03 Javascript
使用Jquery获取带特殊符号的ID 标签的方法
2014/04/30 Javascript
jquery简单图片切换显示效果实现方法
2015/01/14 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
JavaScript中利用jQuery绑定事件的几种方式小结
2016/03/06 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
详解如何构建Promise队列实现异步函数顺序执行
2018/10/23 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
js实现简易拖拽的示例
2020/10/26 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
python分析nignx访问日志脚本分享
2015/02/26 Python
python利用拉链法实现字典方法示例
2017/03/25 Python
python3实现公众号每日定时发送日报和图片
2018/02/24 Python
Python使用爬虫爬取静态网页图片的方法详解
2018/06/05 Python
python Pandas如何对数据集随机抽样
2019/07/29 Python
wxpython布局的实现方法
2019/11/01 Python
python无序链表删除重复项的方法
2020/01/17 Python
详解用Python进行时间序列预测的7种方法
2020/03/13 Python
分享一个python的aes加密代码
2020/12/22 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
HTML5 Canvas 实现圆形进度条并显示数字百分比效果示例
2017/08/18 HTML / CSS
2014年幼儿园园长工作总结
2014/12/17 职场文书
2015年班组建设工作总结
2015/05/13 职场文书
mysql的数据压缩性能对比详情
2021/11/07 MySQL
源码分析Redis中 set 和 sorted set 的使用方法
2022/03/22 Redis