Python Shallow Copy VS. Deep Copy (Python浅拷贝和深拷贝)

Stella981
• 阅读 628

今天电面遇到Python中浅拷贝和深拷贝的区别,平时不经常用当然不知道了,回来就补个课。

先举个非常常见的例子:

import copy

list1 = [1, 2, 3, ['a', 'b']]
list2 = list1
list3 = copy.copy(list1)
list4 = copy.deepcopy(list1)
list1.append(5)
list1[3].append('c')

print 'list1: ', list1
print 'list2: ', list2
print 'list3: ', list3
print 'list4: ', list4

#######################################
list1:  [1, 2, 3, ['a', 'b', 'c'], 5]
list2:  [1, 2, 3, ['a', 'b', 'c'], 5]
list3:  [1, 2, 3, ['a', 'b', 'c']]
list4:  [1, 2, 3, ['a', 'b']]
########################################

从上面这个例子可以看出,如果浅拷贝一个列表,那么系统会新建一个列表,它的每个元素指向原来那个列表的每个元素(就像C语言里的指针数组),输出的时候会把各个元素指向的元素内容显示出来。所以当list1追加了元素5后,list3并没有显示出来,因为list3中并没有指向这个新元素的元素;但是list1[3]追加了'c',list3也追加了'c',是因为list3中有指向'c'所在列表的元素。

而对于深拷贝来说,无论list1作何改变,list4都不会随之改变,是因为深拷贝是新建一个列表,把原来列表的内容原封不动拷过来,是的新的列表和原来的列表一模一样,这是对象资源的拷贝。

可以再参考下面两个例子。

1.浅拷贝

========

import copy

class MyClass:
    def __init__(self, name):
        self.name = name
    def __cmp__(self, other):
        return cmp(self.name, other.name)

a = MyClass('a')
myList = [a]
dup_shallow = copy.copy(myList)
print 'myList: ', myList
print 'dup_shallow: ', dup_shallow
print 'dup_shallow is myList: ', (dup_shallow is myList)
print 'dup_shallow == myList: ', (dup_shallow == myList)
print 'dup_shallow[0] is myList[0]: ', (dup_shallow[0] is myList[0])
print 'dup_shallow[0] == myList[0]', (dup_shallow[0] == myList[0])

######################################################################
myList:       [<__main__.MyClass instance at 0x0000000002264408>]
dup_shallow:  [<__main__.MyClass instance at 0x0000000002264408>]
dup_shallow is myList:  False  # copy又新建了一个列表,dup_shallow中的元素指向myList中的元素
dup_shallow == myList:  True   # 两个列表指向同一块内存地址的内容,则两个列表的内容必定相等
dup_shallow[0] is myList[0]:  True  # 两个对象指向的内存地址相同
dup_shallow[0] == myList[0] True
######################################################################

2.深拷贝

import copy

class MyClass:
    def __init__(self, name):
        self.name = name
    def __cmp__(self, other):
        return cmp(self.name, other.name)

a = MyClass('a')
myList = [a]
dup_deep = copy.deepcopy(myList)
print 'myList: ', myList
print 'dup_deep: ', dup_deep
print 'dup_deep is myList: ', (dup_deep is myList)
print 'dup_deep == myList: ', (dup_deep == myList)
print 'dup_deep[0] is myList[0]: ', (dup_deep[0] is myList[0])
print 'dup_deep[0] == myList[0]', (dup_deep[0] == myList[0])

################################################################
myList:    [<__main__.MyClass instance at 0x0000000002264408>]
dup_deep:  [<__main__.MyClass instance at 0x0000000002264308>]
dup_deep is myList:  False  
dup_deep == myList:  True    # 两个列表虽然指向不同的内存地址,但是内存地址中存储的内容相同
dup_deep[0] is myList[0]:  False  # 两个对象的内存地址不同
dup_deep[0] == myList[0] True
#################################################################
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java 复制Map对象(深拷贝与浅拷贝)
java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
放学路上 放学路上
2年前
python 赋值引用 浅拷贝 深拷贝
一、基础概念1、直接赋值:其实就是对象的引用(别名)。2、浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。3、深拷贝(deepcopy):copy模块的deepcopy方法,完全拷贝了父对象及其子对象。二、代码示例importcopya1,2,3,4,'a','b'原始对象ba
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这