Python中实现变量赋值传递时的引用和拷贝方法


Posted in Python onApril 29, 2018

iamlaosong文

曾经看到这样一个问题,一个字典中的元素是列表,将这个列表元素赋值给一个变量,然后修改这个列表中元素的值,结果发现,字典中那个列表也同样修改了。

那个问题如下:

dict = {'a':[1,2,3,4,5],'b':2} 
x = dict['a'] 
for i in range(5): 
  x[i] = 0 
print(dict['a'])

程序运行结果如下:

[0, 0, 0, 0, 0]

这儿涉及到Python赋值到底是引用还是拷贝一份的问题,即赋值时是传值还是传址。上面问题是将“a”的值赋给了x出现了上述情况,如果是将“b”的值赋给了x,当我们修改x的值时,字典dict的值并不受影响。

>>> dict = {'a':[1,2,3,4,5],'b':2} 
>>> x = dict['b'] 
>>> x 
2 
>>> x=x+3 
>>> x 
5 
>>> dict 
{'a': [1, 2, 3, 4, 5], 'b': 2} 
>>>

那么问题来了,变量赋值传递时什么情况下是传值(拷贝),什么情况下是传址(引用)呢?

1、直接拷贝

当我们不知道是引用还是拷贝的情况下,可以显式的拷贝。比如字典对象本身都具有拷贝的方法:

x=dict.copy()

没有拷贝方法的对象,也是可以拷贝的。这儿我们引入一个深拷贝的概念,深拷贝——即python的copy模块提供的一个deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们对这两个变量中的一个进行任意修改都不会影响其他变量。还是上面的代码,如果改成如下:

import copy 
dict = {'a':[1,2,3,4,5],'b':2} 
x = copy.deepcopy(dict['a']) 
for i in range(5): 
  x[i] = 0 
print(dict['a'])

运行结果dict值不受影响。

除了深拷贝,copy模块还提供一个copy方法,称其为浅拷贝,对于简单的对象,深浅拷贝都是一样的,上面的词典对象的copy方法就是浅拷贝。

>>> dict
{'a': [8, 2, 3, 4, 5], 'b': 4}
>>> dd=copy.copy(dict)
>>> dd
{'a': [8, 2, 3, 4, 5], 'b': 4}
>>> dd['a'][0]=7
>>> dd
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> dict
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> ee=dict.copy()
>>> ee
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> ee['a'][0]=9
>>> ee
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>> dict
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>> ee['b']=5
>>> ee
{'a': [9, 2, 3, 4, 5], 'b': 5}
>>> dict
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>>

浅拷贝时改变第一层次相互不受影响(上例中词典b值的修改),第二层次(上例中词典a的列表值修改)就相互影响了,改一个,其他跟着变。看看id吧:

>>> id(dict) 
20109472 
>>> id(dd) 
20244496 
>>> id(ee) 
20495072 
>>> id(dd['a']) 
20272112 
>>> id(ee['a']) 
20272112 
>>> id(dict['a']) 
20272112 
>>>

可见词典各个拷贝的id是不同的,但词典a值的id是相同的。如果我们需要真正意义的拷贝,就用深拷贝吧。

2、传递规则

Python赋值过程中不明确区分拷贝和引用,一般对静态变量的传递为拷贝,对动态变量的传递为引用。(注,对静态变量首次传递时也是引用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)。

字符串,数值,元组均为静态变量

列表,字典为动态变量。

变量有时比较复杂,存在组合现象,比如字典中包含列表,列表中包含字典,但赋值时,总是属于某个类型。如果实在不清楚状况,可以试验一下,用id()这个函数看看,如果是引用,两个变量指向的地址是相同的。例如:

>>> a=6 
>>> id(a) 
10413476 
>>> b=a 
>>> id(b) 
10413476 
>>> b=8 
>>> id(b) 
10413452 
>>>

修改变量b之前,a和b指向的地址是相同的,修改b后,地址就变了。

以上这篇Python中实现变量赋值传递时的引用和拷贝方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python学习笔记整理3之输入输出、python eval函数
Dec 14 Python
Python操作SQLite数据库的方法详解
Jun 16 Python
深入理解Python中的super()方法
Nov 20 Python
python2.7实现爬虫网页数据
May 25 Python
Python实例方法、类方法、静态方法的区别与作用详解
Mar 25 Python
Django 开发环境与生产环境的区分详解
Jul 26 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
Tensorflow 卷积的梯度反向传播过程
Feb 10 Python
python使用docx模块读写docx文件的方法与docx模块常用方法详解
Feb 17 Python
python使用OpenCV模块实现图像的融合示例代码
Apr 10 Python
Python3将ipa包中的文件按大小排序
Apr 17 Python
Python 中random 库的详细使用
Jun 03 Python
分享一下Python数据分析常用的8款工具
Apr 29 #Python
Python随机函数random()使用方法小结
Apr 29 #Python
Python中py文件引用另一个py文件变量的方法
Apr 29 #Python
python实现类之间的方法互相调用
Apr 29 #Python
Python装饰器原理与简单用法实例分析
Apr 29 #Python
Python2.7 实现引入自己写的类方法
Apr 29 #Python
Python 实现引用其他.py文件中的类和类的方法
Apr 29 #Python
You might like
Yii视图CGridView列表用法实例分析
2016/07/12 PHP
PHP socket 模拟POST 请求实例代码
2016/07/18 PHP
Yii2实现让关联字段支持搜索功能的方法
2016/08/10 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
解析DHTML,JavaScript,DOM,BOM以及WEB标准的描述
2013/06/19 Javascript
JS 退出系统并跳转到登录界面的实现代码
2013/06/29 Javascript
node.js中的fs.linkSync方法使用说明
2014/12/15 Javascript
JavaScript中document.forms[0]与getElementByName区别
2015/01/21 Javascript
JavaScript学习笔记之定时器
2015/01/22 Javascript
轻松实现javascript图片轮播特效
2016/01/13 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
Vue 自定义动态组件实例详解
2018/03/28 Javascript
Node.js JSON模块用法实例分析
2019/01/04 Javascript
JS用最简单的方法实现四舍五入
2019/08/27 Javascript
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
python实现批量视频分帧、保存视频帧
2019/05/31 Python
python元组的概念知识点
2019/11/19 Python
pyftplib中文乱码问题解决方案
2020/01/11 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
Python使用Numpy模块读取文件并绘制图片
2020/05/13 Python
安装并免费使用Pycharm专业版(学生/教师)
2020/09/24 Python
澳大利亚新奇小玩意网站:Yellow Octopus
2017/12/28 全球购物
美国在线眼镜店:GlassesShop
2018/11/15 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
优秀大学生推荐信范文
2013/11/28 职场文书
大二学期个人自我评价
2014/01/13 职场文书
演讲比赛策划方案
2014/06/11 职场文书
党的群众路线学习笔记
2014/11/06 职场文书
教师聘用意向书
2015/05/11 职场文书
暑假打工感想
2015/08/07 职场文书
新员工入职感言范文!
2019/07/04 职场文书
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
CSS实现五种常用的2D转换
2021/12/06 HTML / CSS