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实现删除Android工程中的冗余字符串
Jan 19 Python
简单介绍Ruby中的CGI编程
Apr 10 Python
python判断一个集合是否包含了另外一个集合中所有项的方法
Jun 30 Python
Window环境下Scrapy开发环境搭建
Nov 18 Python
Django管理员账号和密码忘记的完美解决方法
Dec 06 Python
python中几种自动微分库解析
Aug 29 Python
pytorch中的上采样以及各种反操作,求逆操作详解
Jan 03 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
Jun 17 Python
Python datetime 如何处理时区信息
Sep 02 Python
Django前后端分离csrf token获取方式
Dec 25 Python
python opencv实现直线检测并测出倾斜角度(附源码+注释)
Dec 31 Python
Python3+Django get/post请求实现教程详解
Feb 16 Python
python绘图subplots函数使用模板的示例代码
教你怎么用Python处理excel实现自动化办公
解决python绘图使用subplots出现标题重叠的问题
python数据库批量插入数据的实现(executemany的使用)
Apr 30 #Python
Python如何把不同类型数据的json序列化
Apr 30 #Python
python实现三次密码验证的示例
Django一小时写出账号密码管理系统
You might like
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
PHP实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
PHP curl 抓取AJAX异步内容示例
2014/09/09 PHP
php根据生日计算年龄的方法
2015/07/13 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
2016/10/10 PHP
PHP实现导出excel数据的类库用法示例
2016/10/15 PHP
PHP 文件上传限制问题
2019/09/01 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
JavaScript 设计模式 安全沙箱模式
2010/09/24 Javascript
jQuery LigerUI 使用教程入门篇
2012/01/18 Javascript
对象题目的一个坑 理解Javascript对象
2015/12/22 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
canvas实现流星雨的背景效果
2017/01/13 Javascript
Javascript实现找不同色块的游戏
2017/07/17 Javascript
js字符串类型String常用操作实例总结
2019/07/05 Javascript
vue图片上传组件使用详解
2019/12/23 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
Python压缩和解压缩zip文件
2015/02/14 Python
python轻松实现代码编码格式转换
2015/03/26 Python
python获取指定网页上所有超链接的方法
2015/04/04 Python
浅谈python中的__init__、__new__和__call__方法
2017/07/18 Python
python实战教程之自动扫雷
2018/07/13 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
Python实现图片添加文字
2019/11/26 Python
Python爬虫获取豆瓣电影并写入excel
2020/07/31 Python
Python命名空间及作用域原理实例解析
2020/08/12 Python
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
飘柔洗发水广告词
2014/03/14 职场文书
电气工程自动化求职信
2014/03/14 职场文书
优秀班主任推荐材料
2014/12/17 职场文书
防溺水主题班会教案
2015/08/12 职场文书
2016秋季幼儿园开学寄语
2015/12/03 职场文书
2019年思想汇报
2019/06/20 职场文书
react中的DOM操作实现
2021/06/30 Javascript
如何利用python实现列表嵌套字典取值
2022/06/10 Python