Python学习之路:基础知识之深浅拷贝

Posted studying-du

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习之路:基础知识之深浅拷贝相关的知识,希望对你有一定的参考价值。

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.深拷贝

  1. 首先,就深浅拷贝而言,对于str/bool/int这三种数据类型而言是没有区别的,都是在内存中新开辟一块地址去存储。
  2. 深浅拷贝对于list/set/dic三种数据类型而言有区别,当这三种数据类型内部没有嵌套可变数据类型时,深浅拷贝区别不大。
  3. 而当存在嵌套的情况时,浅拷贝只是将第一层数据进行拷贝,嵌套着的第二层数据不拷贝,还是在原来的内存地址,内存地址不会变。而深拷贝则不同,会将第二层的数据也进行拷贝,另辟内存进行保存,所以就算原来的所嵌套的内容有所改变,复制后的也不会改变。

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中的嵌套内容发生变化时,不会影响原来的列表。

 

以上是关于Python学习之路:基础知识之深浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

10Python全栈之路系列之深浅拷贝标准库系列之datetime模块

python之路15学习小结

python之深浅拷贝(基础四)

Python基础之小数据池及深浅拷贝

python之路13python的深浅拷贝

Python之路8-深浅拷贝