python深拷贝和浅拷贝

文章目录

    • 浅拷贝
    • 深拷贝

刷完这60个标准库模块,成为Python骨灰级玩家

深拷贝和浅拷贝都是用于复制对象的概念。浅拷贝在复制对象时,仅复制其引用,而非复制对象本身。这意味着原对象和新对象都指向相同的内存地址,修改一个对象会影响另一个对象。如果有一点C语言基础,那么可能马上意识到,浅拷贝相当于复制了指针,而深拷贝则相当于新开辟了一块内存。。

浅拷贝

现有一个变量a,这个a可能占据大量内存,但在我们看来,这就是一个a而已,换言之,a或许只是提供了一个内存范围,起到一个寻址,或者指示的作用。

当我们调用a的时候,解释器识别了a这个变量,然后将通过a找到了一大片内存。

所谓浅拷贝,比如b=copy.copy(a),这个过程中,仅仅是把a这个索引赋值给了b,至于a所指向的那一大片内存,是纹丝不动的。

import copy
a = [i for i in range(100)]
b = a       # = 默认浅拷贝
id(a)
# 2236793528448
id(b)
# 2236793528448
id(a[0])
# 2236754585872
id(b[0])
# 2236754585872 和 a[0]是同一位置

由此导致的结果就是,如果那片内存发生了什么变化,ab也将同步变化。

print(a[0],b[0])
# 输出 0,0
a[0] = 255
print(a[0],b[0])
# 输出255 255

深拷贝

深拷贝,则可以重新开辟一片内存,让这个新开辟的内存,处处与a指向的那片内存相等。所以,当b=copy.deepcopy(a)被执行后,ab将变得互不相干。

a = [i for i in range(100)]
b = copy.deepcopy(a)
id(a[0])
id(b[0])
# 这时a[0]和b[0]还是指向同样的位置

之所以a[0]b[0]还是指向同一个位置,是因为二者的值是相同的,a[0]==b[0]==0,而0这个对象在整个python运行时中只有一个,所以无论什么对象,只要其中有0,那么这个对象都会指向同一位置

a = [i for i in range(50000)]
c = [i for i in range(50000)]
id(a[0]) == id(c[0])
# a和c没有任何关系,但二者指向了统一内存位置 True

为了确认的确执行了设拷贝,可以更改一下a[i]的值,可以看到b[i]并不会跟着改动。

a[0] = 1
id(a[0])==id(b[0])
# False 即更改a[0]的值后,a[0]和b[0]指向的内存发生了变化

由于深拷贝需要操作大量内存,也会新建大量内存,所以一般情况下,python的赋值号执行的是浅拷贝。

如果不想导入copy模块,同时还想新建一个变量,那么可以结合对象的特点来使用运算符,例如

a = [i for i in range(50000000)]
b = a + []

如果把内存理解为一个宝藏,那么浅拷贝相当于标记了一个领地,而深拷贝相当于另外再挖一个宝藏。

python深拷贝和浅拷贝_第1张图片

你可能感兴趣的:(#,Python标准库,python,deepcopy,深拷贝,浅拷贝)