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对字典进行排序实例
Sep 25 Python
Flask web开发处理POST请求实现(登录案例)
Jul 26 Python
对Python中Iterator和Iterable的区别详解
Oct 18 Python
python2使用bs4爬取腾讯社招过程解析
Aug 14 Python
python编写猜数字小游戏
Oct 06 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
Oct 11 Python
Python 中如何实现参数化测试的方法示例
Dec 10 Python
Python AutoCAD 系统设置的实现方法
Apr 01 Python
学会python自动收发邮件 代替你问候女友
May 20 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
May 25 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
Jun 18 Python
python调用ffmpeg命令行工具便捷操作视频示例实现过程
Nov 01 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
PHP生成便于打印的网页
2006/10/09 PHP
PHP+MYSQL 出现乱码的解决方法
2008/08/08 PHP
php文件上传的例子及参数详解
2013/12/12 PHP
php基础教程
2015/08/26 PHP
php生成酷炫的四个字符验证码
2016/04/22 PHP
Yii实现简单分页的方法
2016/04/29 PHP
php封装的图片(缩略图)处理类完整实例
2016/10/19 PHP
简单谈谈 php 文件锁
2017/02/19 PHP
php实现评论回复删除功能
2017/05/23 PHP
ThinkPHP框架整合微信支付之刷卡模式图文详解
2019/04/10 PHP
用javascript实现无刷新更新数据的详细步骤 asp
2006/12/26 Javascript
用js实现手把手教你月入万刀(转贴)
2007/11/07 Javascript
jQuery在IE下使用未闭合的xml代码创建元素时的Bug介绍
2012/01/10 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
vue使用axios实现文件上传进度的实时更新详解
2017/12/20 Javascript
vue-cli脚手架config目录下index.js配置文件的方法
2018/03/13 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
JavaScript剩余操作符Rest Operator详解
2019/07/20 Javascript
VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法
2020/04/17 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
2020/06/04 Javascript
Python中二维列表如何获取子区域元素的组成
2017/01/19 Python
python监控文件并且发送告警邮件
2018/06/21 Python
Python装饰器模式定义与用法分析
2018/08/06 Python
Python面向对象基础入门之编码细节与注意事项
2018/12/11 Python
美国知名户外用品畅销中心:Sierra Trading Post
2016/07/19 全球购物
意大利值得信赖的在线超级药房:PillolaStore
2020/02/05 全球购物
Linux管理员面试题 Linux admin interview questions
2014/11/01 面试题
某科技软件测试面试题
2013/05/19 面试题
四好少年事迹材料
2014/01/12 职场文书
历史专业大学生职业生涯规划书
2014/03/13 职场文书
住院医师规范化培训实施方案
2014/06/12 职场文书
植树节标语
2014/06/27 职场文书
个人作风建设心得体会
2014/10/22 职场文书
学生上课说话检讨书
2014/10/25 职场文书
2014年民警工作总结
2014/11/25 职场文书
政府会议通知范文
2015/04/15 职场文书