标签:color 变量 rom class lis 创建 复制 进一步 改变
一、赋值
str例
a=‘hello‘ b=‘hello‘ c=a print(id(a),id(b),id(c)) #2518845789440 2518845789440 2518845789440
我们可以发现a,b,c三者的地址是一样的。所以以上赋值的操作就相当于c=a=b=‘hello‘
赋值是系统先给一个变量或者对象分配了内存,然后再将地址赋给a,b,c。所以它们的地址是相同的
list例
a=[‘hello‘] b=[‘hello‘] c=a print(id(a),id(b),id(c)) #1924016299912 1924016299976 1924016299912
但是这种情况却不一样了,a和b的地址不同,为什么
因为str是不可变的,所以同样是‘hello’只有一个地址,但是list是可变的,所以必须分配两个地址
如果以上两种情况修改了值会怎么样
str例
a=‘hello‘ b=‘hello‘ c=a a=‘world‘ print(id(a),id(b),id(c)) #2570701091368 2570703634360 2570703634360
这时a的地址和值变量,但是b,c地址和值都未变。因为str的不可变性,a要重新复制则需要重新开辟内存空间,所以a的值改变,a指向的地址改变,b,c由于‘hello’的不可变性,不会发生改变
list例
a=[‘hello‘] b=[‘hello‘] c=a a[0]=‘world‘ print(id(a),id(b),id(c)) #2476863774600 2476863774664 2476863774600
这时a,c的值和地址均改变,但二者仍相同,b不改变,由于list的可变性,所以修改list的值不需要另外开辟空间,只需修改原地址的值,所以a,c均改变
二、浅拷贝
1 a=[‘hello‘,[123,234]] 2 b=a[:] 3 print(id(a),id(b)) 4 print(id(a[0]),id(a[1])) 5 print(id(b[0]),id(b[1])) 6 7 #2142142193608 2142142197896 8 #2142022964480 2142142193544 9 #2142022964480 2142142193544
我们可以看出a,b地址不同,这符合list是可变的,应开辟不同的空间,我们看第四行和第五行,发现元素的地址也是相同的。如果说字符串‘hello’地址一致还能理解,但是第二个元素的list地址仍一致。这就说明了浅拷贝的特点,只是将容器内的元素的地址复制了一份
接着我们尝试修改a,b中的值
a=[‘hello‘,[123,234]] b=a[:] a[0]=‘world‘ a[1].append(345) print(a) print(b) #[‘world‘, [123, 234, 345]] #[‘hello‘, [123, 234, 345]]
a中第一个元素str改变,但是b中未改变,a中第二个元素改变,b中也改变,这就符合不可变的对象修改会开辟新的空间,可变的对象修改不会开辟新空间,也进一步证明了浅拷贝仅仅是复制了容器中元素的地址
三、深拷贝
from copy import deepcopy a=[‘hello‘,[123,234]] b=deepcopy(a) print(id(a),id(b)) print(id(a[0]),id(a[1])) print(id(b[0]),id(b[1]))
#2576042483656 2576042487944
#2575924887480 2576042483592
#2575924887480 2576042488136
深拷贝后,可以发现a,b地址以及a,b中元素地址均不同。这才是完全拷贝了一个副本
1 from copy import deepcopy 2 a=[‘hello‘,[123,234]] 3 b=deepcopy(a) 4 5 a[0]=‘world‘ 6 a[1].append(345) 7 print(a) 8 print(b)
#[‘world‘, [123, 234, 345]]
#[‘hello‘, [123, 234]]
从打印结果来看仅仅a修改了,b没有任何修改。因为b是一个完全的副本,元素地址均与a不同,a修改,b不受影响
总结
1、赋值是将一个对象的地址赋值给一个变量,让变量指向改地址
2、浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是原对象的元素的地址的拷贝,也就是说新的容器中指向了旧的元素
3、深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本
标签:color 变量 rom class lis 创建 复制 进一步 改变
原文地址:https://www.cnblogs.com/z-x-y/p/9893084.html