Python中的复制操作及copy模块中的浅拷贝与深拷贝方法


Posted in Python onJuly 02, 2016

程序中常常需要复制一个对象, 按思路应该是这样的

a = [1, 2, 3]
b = a

# [1, 2, 3]
print b

已经复制好了,但是现在得改变一下第一个元素的值把它改成5

b[0] = 5 

# [5, 2, 3]
print b 

# [5, 2, 3]
print a

我改变了b的第一个元素的值,但是a的值也改变了,这是因为python中的=是引用.a和b指向的是相同的列表,所以改变列表会出现以上的结果.

解决方法是切片操作

a = [1, 2, 3]
b = a[:]
b[0] = 4

# [1, 2, 3]
# [4, 2, 3]
print a
print b

但是在嵌套列表的时候呢,试一试

a = [[1,2,3], 4, 5]
b = a[:]
b[1] = 0 

# [[1,2,3], 4, 5]
# [[1,2,3], 0, 5]
print a
print b

恩!没什么问题,在试一试嵌套列表元素

a = [[1,2,3], 4, 5]
b = a[:]
b[0][0] = 5

# [[5,2,3], 4, 5]
# [[5,2,3], 4, 5]
print a
print b
b = a[:]

a的值还是改变了,切片复制只对该对象进行拷贝不会对子元素进行拷贝

copy 模块

copy模块用于对象的拷贝操作。该模块非常简单,只提供了两个主要的方法: copy.copy 与 copy.deepcopy ,分别表示浅复制与深复制。什么是浅复制,什么是深复制,网上有一卡车一卡车的资料,这里不作详细介绍。复制操作只对复合对象有效。用简单的例子来分别介绍这两个方法。

浅复制只复制对象本身,没有复制该对象所引用的对象。

#coding=gbk
import copy
l1 = [1, 2, [3, 4]]
l2 = copy.copy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2

结果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
[1, 2, [50, 4]]

同样的代码,使用深复制,结果就不一样:

import copy
l1 = [1, 2, [3, 4]]
l2 = copy.deepcopy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2

结果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]

改变copy的默认行为

在定义类的时候,通过定义__copy__和__deepcopy__方法,可以改变copy的默认行为。下面是一个简单的例子:

class CopyObj(object):
  def __repr__(self):
    return "CopyObj"
  
  def __copy__(self):
    return "Hello"
obj = CopyObj()
obj1 = copy.copy(obj)
print obj
print obj1

结果:

CopyObj
Hello
Python 相关文章推荐
python实现根据月份和日期得到星座的方法
Mar 27 Python
讲解Python中的递归函数
Apr 27 Python
Python文档生成工具pydoc使用介绍
Jun 02 Python
详解在Python程序中自定义异常的方法
Oct 16 Python
浅谈pyhton学习中出现的各种问题(新手必看)
May 17 Python
Django自定义manage命令实例代码
Feb 11 Python
python实战之实现excel读取、统计、写入的示例讲解
May 02 Python
Python使用pyshp库读取shapefile信息的方法
Dec 29 Python
python requests 库请求带有文件参数的接口实例
Jan 03 Python
Python OS模块实例详解
Apr 15 Python
django 邮件发送模块smtp使用详解
Jul 22 Python
pytorch中index_select()的用法详解
Jan 06 Python
快速排序的算法思想及Python版快速排序的实现示例
Jul 02 #Python
Python使用functools模块中的partial函数生成偏函数
Jul 02 #Python
Python之父谈Python的未来形式
Jul 01 #Python
举例讲解Python的lambda语句声明匿名函数的用法
Jul 01 #Python
Python内置数据结构与操作符的练习题集锦
Jul 01 #Python
Python设置默认编码为utf8的方法
Jul 01 #Python
Python使用email模块对邮件进行编码和解码的实例教程
Jul 01 #Python
You might like
ajax+php打造进度条代码[readyState各状态说明]
2010/04/12 PHP
比较时间段一与时间段二是否有交集的php函数
2011/05/31 PHP
PHP产生不重复随机数的5个方法总结
2014/11/12 PHP
php站内搜索关键词变亮的实现方法
2014/12/30 PHP
yum命令安装php7和相关扩展
2016/07/04 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
2017/09/30 PHP
原生php实现excel文件读写的方法分析
2018/04/25 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
2019/11/14 PHP
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
2015/02/26 Javascript
jquery实现的动态回到顶部特效代码
2015/10/28 Javascript
JQuery核心函数是什么及使用方法介绍
2016/05/03 Javascript
AngularJS使用指令增强标准表单元素功能
2016/07/01 Javascript
Vue.js实现模拟微信朋友圈开发demo
2017/04/20 Javascript
小程序两种滚动公告栏的实现方法
2019/09/17 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
2020/09/24 Javascript
wxpython中利用线程防止假死的实现方法
2014/08/11 Python
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
在Lighttpd服务器中运行Django应用的方法
2015/07/22 Python
Django 生成登陆验证码代码分享
2017/12/12 Python
Python读写及备份oracle数据库操作示例
2018/05/17 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
pyqt5移动鼠标显示坐标的方法
2019/06/21 Python
python导包的几种方法(自定义包的生成以及导入详解)
2019/07/15 Python
python opencv 简单阈值算法的实现
2019/08/04 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
2020/01/18 Python
Python计算IV值的示例讲解
2020/02/28 Python
Python通过socketserver处理多个链接
2020/03/18 Python
CSS3实现的文本3D效果附图
2014/09/03 HTML / CSS
CSS3 flex布局之快速实现BorderLayout布局
2015/12/03 HTML / CSS
Html5饼图绘制实现统计图的方法
2020/08/05 HTML / CSS
我的求职计划书
2014/01/10 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
2015年幼儿教育工作总结
2015/07/24 职场文书
Spring JPA 增加字段执行异常问题及解决
2022/06/10 Java/Android