本文章纯野生,无任何借鉴他人文章及抄袭等。坚持原创!!
这是一个面试题。请简述Python的浅拷贝和深拷贝?
看到别人的文章,都带有画图的。虽说一图千文,但灵魂画手并不适合画图,所以这里使用简洁明了的句子去阐释浅拷贝与深拷贝。
先说概念:
这里还要说一个概念,就是Python的可变对象和不可变对象。
官方文档释义:
个人理解:
可变对象:通俗点讲就是一个对象在修改它的值时候,不会改变该对象所指向的内存地址。
不可变对象:与可变对象相反。
浅拷贝:浅拷贝只是复制外围的一层数据,内部的数据只是引用了原来的内存地址
深拷贝:对外围和内部元素都进行了拷贝对象本身,而不是对象的引用
不可变类型数据没有所谓的深浅拷贝,都是对源对象内存地址的引用、赋值也是对内存地址的引用。
Python常见的数据结构。
对象 | 可变对象 | 不可变对象 |
---|---|---|
整数int | √ | |
元组tuple | √ | |
字符串str | √ | |
浮点数float | √ | |
布尔值bool | √ | |
列表list | √ | |
集合set | √ | |
字典dict | √ |
建议移步Python官方中文文档系统性的了解这几个概念。
下面上例子,包懂!!!
Python的 == 是判断两个对象的值是否相等,is则是判断两个对象的内存地址是否相等。
来看下面一则例子。
>>>a = [1, 2, 3]
>>>b = [1, 2, 3] # 创建两个a、b两个列表
>>>a == b # 判断a、b两个对象的值是否相等
True
>>>a is b # 判断a、b两个对象的内存地址是否相等
False
>>>id(a),id(b) # 打印输出两个对象的内存地址,发现不一样
(2692110484296, 2692110525256)
例如一个列表里面嵌套了另一个列表:[1, 2, 3, [4, 5]]
>>>import copy # 导入模块
>>>a = [1, 2, 3, [4, 5]]
>>>b = copy.copy(a) # 使用浅拷贝拷贝a对象
>>>b # 打印输出b
[1, 2, 3, [4, 5]]
>>>id(a),id(b) # 打印输出a、b的内存地址
(2692110485192, 2692110468616)
>>>a is b # a和b的内存地址不相等,所以返回False
False
>>>a[3] is idb[3] # 内层的b的[4,5]实际上是引用了a的[4,5]内存地址,即他们是相等的
True
>>>a[3][1] = 10 # 更改a的内层列表的第二个元素
>>>a # 打印输出a
[1, 2, 3, [4, 10]]
>>>b # 打印输出b,可以看到b也随之更改了。
[1, 2, 3, [4, 10]]
相信看过上述的例子之后,你已经理解何为浅拷贝了。
例如一个列表里面嵌套了另一个列表:[1, 2, 3, [4, 5]]
>>>import copy # 导入模块
>>>a = [1, 2, 3, [4, 5]]
>>>b = copy.deepcopy(a) # 使用深拷贝拷贝a对象
>>>id(a),id(b) # 打印输出a、b的内存地址
(2692110512008, 2692110620872)
>>>a is b # 对象a、b内存地址不一样,这里为False
False
>>>a[3] is b[3] # 对象内层地址也不一样,这里为False
False
>>>a[3][1] = 10 # 更改a的内层列表的第二个元素
>>>a # 打印输出a
[1, 2, 3, [4, 10]]
>>>b # 打印输出b,可以看到b并没有随之改变
[1, 2, 3, [4, 5]]
相信看到这里你已经能理解浅拷贝和深拷贝了。
文章写的很菜,勿喷。
本意是用简洁明了的话介绍一下浅拷贝和深拷贝,没想到却是很啰嗦。
不过啰嗦就归啰嗦,当是做一个笔记吧。
好了,本次的分享到此结束。
有任何疑问欢迎在下方留言哦。