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爬虫框架talonspider简单介绍
Jun 09 Python
Python中pygal绘制雷达图代码分享
Dec 07 Python
对python 各种删除文件失败的处理方式分享
Apr 24 Python
详解Django解决ajax跨域访问问题
Aug 24 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
Oct 22 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
May 04 Python
PyQt5实现简易电子词典
Jun 25 Python
djano一对一、多对多、分页实例代码
Aug 16 Python
TensorFlow2.X使用图片制作简单的数据集训练模型
Apr 08 Python
keras做CNN的训练误差loss的下降操作
Jun 22 Python
selenium自动化测试入门实战
Dec 21 Python
使用qt quick-ListView仿微信好友列表和聊天列表的示例代码
Jun 13 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
php数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
2011/11/02 PHP
PHP设计模式之责任链模式的深入解析
2013/06/13 PHP
php字符比较函数similar_text、strnatcmp与strcasecmp用法分析
2014/11/18 PHP
ThinkPHP3.2.3框架邮件发送功能图文实例详解
2019/04/23 PHP
Laravel 关联模型-关联新增和关联更新的方法
2019/10/10 PHP
jquery 指南/入门基础
2007/11/30 Javascript
jquery刷新页面的实现代码(局部及全页面刷新)
2011/07/11 Javascript
javascript中的void运算符语法及使用介绍
2013/03/10 Javascript
escape编码与unescape解码汉字出现乱码的解决方法
2014/07/02 Javascript
js使用心得分享
2015/01/13 Javascript
JS模拟实现Select效果代码
2015/09/24 Javascript
浅析JavaScript Array和string的转换(推荐)
2016/05/20 Javascript
基于bootstrap实现广告轮播带图片和文字效果
2016/07/22 Javascript
JS图片压缩(pc端和移动端都适用)
2017/01/12 Javascript
Bootstrap常用组件学习(整理)
2017/03/24 Javascript
Angular4学习教程之HTML属性绑定的方法
2018/01/04 Javascript
在vue-cli项目中使用bootstrap的方法示例
2018/04/21 Javascript
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
原生JavaScript之es6中Class的用法分析
2020/02/23 Javascript
Vue微信公众号网页分享的示例代码
2020/05/28 Javascript
[49:31]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第二场 1月29日
2021/03/11 DOTA
python中split方法用法分析
2015/04/17 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
Python中print和return的作用及区别解析
2019/05/05 Python
python定位xpath 节点位置的方法
2019/08/27 Python
Python标准库json模块和pickle模块使用详解
2020/03/10 Python
伦敦高级内衣品牌:Agent Provocateur(大内密探)
2016/08/23 全球购物
string = null 和string = ''的区别
2013/04/28 面试题
大专生毕业的自我评价
2014/02/06 职场文书
企业办公室主任岗位职责
2014/02/19 职场文书
初二学习计划书范文
2014/04/27 职场文书
大学生个人总结范文
2015/02/15 职场文书
审美与表现自我评价
2015/03/09 职场文书
监理中标通知书
2015/04/16 职场文书
2019个人工作自我评价范文(3篇)
2019/09/19 职场文书