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中if __name__ == "__main__"详细解释
Oct 21 Python
Python提取网页中超链接的方法
Sep 18 Python
Python实现判断字符串中包含某个字符的判断函数示例
Jan 08 Python
利用python的socket发送http(s)请求方法示例
May 07 Python
Python应用库大全总结
May 30 Python
详解python:time模块用法
Mar 25 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
Jun 03 Python
运行tensorflow python程序,限制对GPU和CPU的占用操作
Feb 06 Python
Selenium常见异常解析及解决方案示范
Apr 10 Python
PyQt5实现画布小程序
May 30 Python
python seaborn heatmap可视化相关性矩阵实例
Jun 03 Python
Python数据分析入门之教你怎么搭建环境
May 13 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初学者头疼十四条问题大总结
2008/11/12 PHP
国外PHP程序员的13个好习惯小结
2012/02/20 PHP
PHP工厂模式、单例模式与注册树模式实例详解
2019/06/03 PHP
PHP设计模式之迭代器模式Iterator实例分析【对象行为型】
2020/04/26 PHP
图片自动缩小的js代码,用以防止图片撑破页面
2007/03/12 Javascript
解析window.open的使用方法总结
2013/06/19 Javascript
鼠标选择动态改变网页背景颜色的JS代码
2013/12/10 Javascript
jQuery简单实现网页选项卡特效
2014/11/24 Javascript
web前端开发JQuery常用实例代码片段(50个)
2015/08/28 Javascript
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
js实现图片旋转 js滚动鼠标中间对图片放大缩小
2017/07/05 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
微信小程序实现刷脸登录
2018/05/25 Javascript
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
2018/09/20 Javascript
video.js 一个页面同时播放多个视频的实例代码
2018/11/27 Javascript
Vue中函数防抖节流的理解及应用实现
2020/04/24 Javascript
[03:01]2014DOTA2国际邀请赛 DC:我是核弹粉,为Burning和国土祝福
2014/07/13 DOTA
Python入门篇之字典
2014/10/17 Python
简单讲解Python中的闭包
2015/08/11 Python
Python 数据结构之旋转链表
2017/02/25 Python
Django 使用logging打印日志的实例
2018/04/28 Python
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
OpenCV搞定腾讯滑块验证码的实现代码
2019/05/18 Python
python使用minimax算法实现五子棋
2019/07/29 Python
基于Python实现体育彩票选号器功能代码实例
2020/09/16 Python
Scrapy中如何向Spider传入参数的方法实现
2020/09/28 Python
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
Under Armour安德玛荷兰官网:美国高端运动科技品牌
2019/07/10 全球购物
《奇妙的国际互联网》 教学反思
2014/02/25 职场文书
个人整改措施落实情况汇报
2014/10/29 职场文书
2014年学校工作总结
2014/11/20 职场文书
大学生学年个人总结
2015/02/15 职场文书
上班迟到检讨书范文
2015/05/06 职场文书
后天观后感
2015/06/08 职场文书
python pygame入门教程
2021/06/01 Python