Python浅拷贝和和深拷贝
2016-04-17 17:48
399 查看
Python提供了copy模块,用于对象的拷贝操作,包括copy和deepcopy两个函数,分别用于浅拷贝和深拷贝,以下分析两者的差异:
1. 父对象中包含可变对象
首先给出一个例子:
b为a的对象引用,c使用copy实现对a的浅拷贝,d使用deepcopy实现对a的深拷贝。
随后向a和a[3]中分别添加了新的元素'a_app'以及'sub_app'。
运行程序,输出结果如下:
可以看到:
(1) a和b完全为同一个东西,从id(a)==id(b)即可看出,a的操作将完全同步到b。
(2) c为a的浅拷贝,a操作不影响c,但a的子对象操作影响c。这是因为浅拷贝只是拷贝了父对象,没有拷贝子对象,c中子对象列表完全是a中子对象列表的引用。
(3) d为a的深拷贝,无论a的操作还是a的子对象的操作,对d均无影响。这是因为深拷贝对父对象和子对象均进行了操作,d中所有元素均是新创建的,与拷贝源a无任何关联。
2. 父对象中无可变对象
以上例子中,父对象a列表中包含新列表,为可变对象。当父对象中所有元素均为不可变对象时,情况又是怎样的?
程序运行结果如下:
可见,对lista的操作并没有影响listb,listb虽是浅拷贝,但其对象及内容均是全新的。
3. 总结
(1) 浅拷贝和深拷贝都产生了一个新的对象,从拷贝后两者id不同可知。
(2) 浅拷贝内容并不是全新创建的,而是父对象的引用。
(3) 深拷贝无论对象还是内容都是全新的,拷贝完成后父对象任何修改均对其无任何影响。
(4) 以上说的的浅拷贝和深拷贝的差异,仅仅是在父对象中包含可变对象(如列表,字典等)时才成立。当父对象中所有对象元素都不可变时(如数字,字符串,元组等),两者并无差异,即使浅拷贝,其对象和内容都是全新生成的。
1. 父对象中包含可变对象
首先给出一个例子:
import copy a = [1,2,3,['abc','def']] b = a #对象引用 c = copy.copy(a) #浅拷贝 d = copy.deepcopy(a) #深拷贝 print ('修改前:') print ('a = ', a) print ('b = ', b) print ('c = ', c) print ('d = ', d) print () print ('id(a)=', id(a)) print ('id(b)=', id(b)) print ('id(c)=', id(c)) print ('id(d)=', id(d)) print () a.append('a_app') #向a附加新元素 a[3].append('sub_app') #向a子列表附加新元素 print ('修改后:') print ('a = ', a) print ('b = ', b) print ('c = ', c) print ('d = ', d)以上程序创建列表a,其中a[3]同样是个列表。
b为a的对象引用,c使用copy实现对a的浅拷贝,d使用deepcopy实现对a的深拷贝。
随后向a和a[3]中分别添加了新的元素'a_app'以及'sub_app'。
运行程序,输出结果如下:
可以看到:
(1) a和b完全为同一个东西,从id(a)==id(b)即可看出,a的操作将完全同步到b。
(2) c为a的浅拷贝,a操作不影响c,但a的子对象操作影响c。这是因为浅拷贝只是拷贝了父对象,没有拷贝子对象,c中子对象列表完全是a中子对象列表的引用。
(3) d为a的深拷贝,无论a的操作还是a的子对象的操作,对d均无影响。这是因为深拷贝对父对象和子对象均进行了操作,d中所有元素均是新创建的,与拷贝源a无任何关联。
2. 父对象中无可变对象
以上例子中,父对象a列表中包含新列表,为可变对象。当父对象中所有元素均为不可变对象时,情况又是怎样的?
import copy lista = [1,2,3,4] listb = copy.copy(lista) print ('修改前:') print ('lista = ', lista) print ('listb = ', listb) print () print ('id(lista) = ', id(lista)) print ('id(listb) = ', id(listb)) print () lista [1] = 100 print ('修改后:') print ('lista = ', lista) print ('listb = ', listb)lista中所有元素均是不可变的,listb使用copy实现对lista的浅拷贝。
程序运行结果如下:
可见,对lista的操作并没有影响listb,listb虽是浅拷贝,但其对象及内容均是全新的。
3. 总结
(1) 浅拷贝和深拷贝都产生了一个新的对象,从拷贝后两者id不同可知。
(2) 浅拷贝内容并不是全新创建的,而是父对象的引用。
(3) 深拷贝无论对象还是内容都是全新的,拷贝完成后父对象任何修改均对其无任何影响。
(4) 以上说的的浅拷贝和深拷贝的差异,仅仅是在父对象中包含可变对象(如列表,字典等)时才成立。当父对象中所有对象元素都不可变时(如数字,字符串,元组等),两者并无差异,即使浅拷贝,其对象和内容都是全新生成的。
相关文章推荐
- Python之我见
- python中的random模块学习
- Python调用哈工大语言云(LTP)API进行自然语言处理
- Python运算符
- python显示系统信息脚本
- CS231n - CNN for Visual Recognition Assignment1 ---- KNN
- Python处理错误三种方式
- Python中的字典(dict)
- <Python><Ubuntu>安装geopandas
- Python 列表 (List)
- Python 集合(set)类型的操作
- Python中的序列结构数据类型
- Scikit-learn学习笔记(一)
- python安装遇到的问题
- pip安装mysql-python报致命错误:my_config.h:没有那个文件或目录
- python.杨辉三角.生成器
- 机器学习算法——感知机(Python源码)
- 初试Visual Studio Code配置Python开发环境
- 在python(windows操作系统)中安装、配置Tushare,希望对股票有兴趣的程序员有一点点帮助
- 关于python实现二维数组所有元素求和