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

 

上一篇:c++ list使用方式


下一篇:C++ | STL 浅谈list容器