1.is和==的区别
== 比较左右两边的值,如果相同,打印的是True,如果不同,打印的是False
1 n = 10 2 n1 = 12 3 print(n == n1) #False
is比较的是内存地址
1 a = 'dhj' 2 b = 'dhj' 3 print(a is b) # True
1 a = 'a'*21 2 b = 'a'*21 3 print(a is b) #false
为什么第二个程序中的结果会是False呢,这涉及到一个小数据池的概念:
- 小数据池只限制于数值和字符串,数值的范围:-5至256
-
字符串中如果有特殊字符如+ - * 等,他们的内存地址就会不一样
- 字符串单个乘以20以内的话,内存地址是一样的
-
以上限于cmd终端中,在PYcharm中不一定适用
2.深拷贝
- 首先,就深浅拷贝而言,对于str/bool/int这三种数据类型而言是没有区别的,都是在内存中新开辟一块地址去存储。
- 深浅拷贝对于list/set/dic三种数据类型而言有区别,当这三种数据类型内部没有嵌套可变数据类型时,深浅拷贝区别不大。
- 而当存在嵌套的情况时,浅拷贝只是将第一层数据进行拷贝,嵌套着的第二层数据不拷贝,还是在原来的内存地址,内存地址不会变。而深拷贝则不同,会将第二层的数据也进行拷贝,另辟内存进行保存,所以就算原来的所嵌套的内容有所改变,复制后的也不会改变。
2.1 赋值
1 lst1 = ['紫衫龙王', '青翼蝠王', '金毛狮王', '白眉鹰王'] 2 lst2 = lst1 3 lst1.append('张无忌') 4 print(lst2)
对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制一份内容. 所以. lst1的内存指向和lst2是一样的. lst1改变了, lst2也发生了改变
2.2 浅拷贝
1 lst1 = ['紫衫龙王', '青翼蝠王', '金毛狮王', ['白眉鹰王', '赵本山']] 2 lst2 = lst1.copy() 3 lst2[3].append('新成员') 4 print(lst1) 5 print(id(lst1[3]), id(lst2[3])) 6 # 结果:['紫衫龙王', '青翼蝠王', '金毛狮王', ['白眉鹰王', '赵本山', '新成员']] 7 # 2049414915328 2049414915328
从运行结果中可以看到,当拷贝后的lst2进行添加新元素的操作时,原来的列表发生了改变,这说明嵌套列表中的内容并没有完全拷贝到lst2,新旧列表中关于其内存地址也是相同的,浅拷贝只是将嵌套列表的内存地址进行了拷贝。
2.3 深拷贝
1 import copy 2 lst1 = ['紫衫龙王', '青翼蝠王', '金毛狮王', '白眉鹰王', ['赵敏', '周芷若']] 3 lst2 = copy.deepcopy(lst1) 4 lst2[4].append('新成员') 5 print(lst1, lst2) 6 print(id(lst1[4]), id(lst2[4])) 7 print(id(lst1), id(lst2)) 8 # 结果:['紫衫龙王', '青翼蝠王', '金毛狮王', '白眉鹰王', ['赵敏', '周芷若']] 9 # ['紫衫龙王', '青翼蝠王', '金毛狮王', '白眉鹰王', ['赵敏', '周芷若', '新成员']] 10 # 2572522151232 2572522346240 11 # 2572522149120 2572522346880
可以看出,深拷贝将嵌套内容完全拷贝,新开辟内存进行保存,当复制版的lst2中的嵌套内容发生变化时,不会影响原来的列表。