Talk is cheap,show me the code!
a = [1, 2]
b = [3, 4]
c = [a, b]
d = c.copy()
#d = copy.copy(c) 这样写也可
print(id(c), id(d))
print(c)
"""
4478043008 4477684864
可以看到浅拷贝的内存地址不同,不是一个对象
"""
print(id(c[0]),id(c[1]))
print(id(d[0]),id(d[1]))
"""
4439315200 4439315392
4439315200 4439315392
可以看到浅拷贝的子对象还是原来的对象
"""
a.append(-1)
print(c, d)
"""
[[1, 2, -1], [3, 4]] [[1, 2, -1], [3, 4]]
可以看到浅拷贝改变子对象时,会随着子对象的改变而改变
"""
c.append(-2)
print(c, d)
"""
[[1, 2, -1], [3, 4], -2] [[1, 2, -1], [3, 4]]
可以看到d是c的浅拷贝,当改变c时,d不会跟着改变
"""
d.append(-3)
print(c, d)
"""
[[1, 2, -1], [3, 4], -2] [[1, 2, -1], [3, 4], -3]
可以看到d是c的浅拷贝,当改变d时,c也不会跟着改变
"""
import copy
a = [1, 2]
b = [3, 4]
c = [a, b]
d = copy.deepcopy(c)
print(id(c), id(d))
"""
4510807168 4509967488
可以看到深拷贝的内存地址不同,等于new了一个新对象
"""
print(id(c[0]),id(c[1]))
print(id(d[0]),id(d[1]))
"""
4481958848 4482719552
4482842560 4482868032
可以看到深拷贝的子对象也没有被拷贝,内存地址也不同
"""
a.append(0)
print(c,d)
"""
[[1, 2, 0], [3, 4]] [[1, 2], [3, 4]]
可以看到深拷贝及时原来对象的子对象发生变化,深拷贝的对象也不会发生变化
"""
c.append(-1)
d.append(-2)
print(c,d)
"""
[[1, 2, 0], [3, 4], -1] [[1, 2], [3, 4], -2]
可以看到d是c的深拷贝,其中一个发生变化与另一个毫不相干
"""
"""
== 和 is 的区别:
== 和 is 是python中常用的两种比较方式,区别如下:
a.__eq__(b)
而python大部分数据类型都会去重载__eq__这个函数,内部的处理会更复杂,例如在列表中,__eq__函数会遍历列表中的所有元素,比较它们的顺序和值是否相等。
l1 = [1,2]
l2 = l1[:]
l1 == l2
True
l1 is l2
False
a = (1,2)
b = a[:]
print(id(a))
print(id(b))
print(a is b)
输出:
4487071104
4487071104
True
import copy
x=[2]
x.append(x)
print(x)
y = copy.deepcopy(x)
print(y)
输出:
[2, [...]]
[2, [...]]
但是我们发现deepcopy后,x中本身存在对自身的引用,x是一个无限嵌套的列表,但是y是x的深拷贝,程序并没有出现stack overflow,原因是深拷贝函数deepcopy中维护了一个字典,记录已经拷贝对象和它的id,拷贝过程中如果字典里已经存储了将要拷贝的对象,则会直接从字典中返回。相应的源码:
def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
if memo is None:
memo = {}
d = id(x)
y = memo.get(d, _nil)
if y is not _nil:
return y
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。