在我们默认意识中,一说到拷贝,大家理所应当地会认为:“拷贝后的数据和源数据只是值相同罢了,而一方的改变不会对另外一方造成影响”。对,这种公认的概念就是Python深拷贝(copy.deepcopy())的直观解释。
但是,计算机在处理Python程序的时候,有的时候并不是按照我们人类思维如此的直观了当,所以就存在了浅拷贝(copy.copy())和赋值(=)。这三者之间的概念容易搞混,下面通过代码展示。
Python中id()函数返回对象的唯一标识符,在解释这三者之间的概念的时候,可以通过id()函数更直观的展现。
目录
一、赋值(=)
二、浅拷贝(copy.copy())
三、深拷贝(copy.deepcopy())
一、赋值(=)
直观理解:赋值的是地址,因此不管源数据和赋值后的数据怎么变,因为指向元素的地址是一样的,所以,a与b的值一直相等。
"""赋值"""
a = [1,2,3,[4,5],6]
b = a
print("a的地址:",id(a))
print("b的地址:",id(b))
print("a中各个元素的地址:",list(id(i) for i in a))
print("b中各个元素的地址:",list(id(i) for i in b))
print("#################################")
a[0]=9
print("改变后的值,a:",a)
print("改变后的值,b:",b)
运行结果:
a的地址: 1624960881672 b的地址: 1624960881672 a中各个元素的地址: [140728839074064, 140728839074096, 140728839074128, 1624960881160, 140728839074224] b中各个元素的地址: [140728839074064, 140728839074096, 140728839074128, 1624960881160, 140728839074224] ################################# 改变后的值,a: [9, 2, 3, [4, 5], 6] 改变后的值,b: [9, 2, 3, [4, 5], 6] Process finished with exit code 0
二、浅拷贝(copy.copy())
深拷贝和浅拷贝都需要用到copy包,记得提前导入
"""浅拷贝"""
import copy #需要导入copy包
a = [1, 2, 3, [4, 5], 6]
b = copy.copy(a)
print("a的地址:",id(a))
print("b的地址:",id(b))
print("a中各个元素的地址:",list(id(i) for i in a))
print("b中各个元素的地址:",list(id(i) for i in b))
print("#################################")
a[0]=9
print("改变后的值,a:",a)
print("改变后的值,b:",b)
print("#################################")
a[3][0] = 8
print("改变嵌套数据后的值,a:",a)
print("改变变嵌套数据后的值,b:",b)
运行结果:
a的地址: 2671219558920 b的地址: 2671219558280 a中各个元素的地址: [140728859586832, 140728859586864, 140728859586896, 2671219589960, 140728859586992] b中各个元素的地址: [140728859586832, 140728859586864, 140728859586896, 2671219589960, 140728859586992] ################################# 改变后的值,a: [9, 2, 3, [4, 5], 6] 改变后的值,b: [1, 2, 3, [4, 5], 6] ################################# 改变后的值,a: [9, 2, 3, [8, 5], 6] 改变后的值,b: [1, 2, 3, [8, 5], 6] Process finished with exit code 0
三、深拷贝(copy.deepcopy())
直观理解:经过深拷贝操作后,前后数据的变化互不影响。
"""深拷贝"""
import copy #需要导入copy包
a = [1, 2, 3, [4, [7,8]], 6]
b = copy.deepcopy(a)
print("a的地址:",id(a))
print("b的地址:",id(b))
print("a中各个元素的地址:",list(id(i) for i in a))
print("b中各个元素的地址:",list(id(i) for i in b))
print("#################################")
a[0]=9
print("改变后的值,a:",a)
print("改变后的值,b:",b)
print("#################################")
a[3][0] = 8
print("改变嵌套数据后的值,a:",a)
print("改变变嵌套数据后的值,b:",b)
a[3][1][0] = 8
print("改变嵌套数据后的值,a:",a)
print("改变变嵌套数据后的值,b:",b)
运行结果:
a的地址: 2649326638088 b的地址: 2649331518344 a中各个元素的地址: [140728859586832, 140728859586864, 140728859586896, 2649331517384, 140728859586992] b中各个元素的地址: [140728859586832, 140728859586864, 140728859586896, 2649326637576, 140728859586992] ################################# 改变后的值,a: [9, 2, 3, [4, [7, 8]], 6] 改变后的值,b: [1, 2, 3, [4, [7, 8]], 6] ################################# 改变嵌套数据后的值,a: [9, 2, 3, [8, [7, 8]], 6] 改变变嵌套数据后的值,b: [1, 2, 3, [4, [7, 8]], 6] 改变嵌套数据后的值,a: [9, 2, 3, [8, [8, 8]], 6] 改变变嵌套数据后的值,b: [1, 2, 3, [4, [7, 8]], 6] Process finished with exit code 0



