7、深浅copy
作者:互联网
查看变量值存储的地址:id(变量)
一、变量
1、
a = 1
b = a
print(a)
print(b)
print(id(a))
print(id(b))
结果:
1
1
2079049648
2079049648
结论:
地址打印结果可以看出a和b的地址指向是一样的都为2079049648。
2、 a = 1 b = a a = 2 print(id(a)) print(id(b)) 结果: 2 1 2079049664 2079049648 结论: 当我们重新给a赋值后,a就指向了新的地址2079049664,新的地址值中存储的值为2,所以a变成了2。 但是b还是等于1,这是因为b还是指向了原来的地址2079049648,所以b的值不变
二、列表 b列表等于a列表 1、 a = [1, 2, 3, 4] b = a print(a) print(b) print(id(a)) print(id(b)) 结果: [1, 2, 3, 4] [1, 2, 3, 4] 13889096 13889096 结果: 列表b等于列表a后地址值是一样的,表示列表b和a都指向了同一个地址值13889096 2、改变列表a中索引位0上的元素值 a = [1, 2, 3, 4] b = a print(a) print(b) print(id(a)) print(id(b)) print(id(a[0])) print(id(b[0])) print("-------改变列表a中索引位0上的元素值------") a[0] = 5 print(a[0]) print(b[0]) print(id(a[0])) print(id(b[0])) 结果: [1, 2, 3, 4] [1, 2, 3, 4] 17296968 17296968 1378731952 1378731952 -------改变列表a中索引位0上的元素值------ 5 5 1378732016 1378732016 列表a索引0的值和列表b索引0的值被一同改变了,但是按照我们前面的笔记(一、变量 2)中的结论来看应 该只会改变列表b的值,实际上导致这种原因是因为列表的内存结构导致的。 结论: 在列表中每个元素都是单独存在的,当元素索引0的元素被改变后,索引0会指向新的地址,而列表b=列表a,所以都指向同一个列表,因此我们会看到列表a和b中的值被一同改变了
三、列表b copy列表a 1、 a = [1, 2, 3, 4] b = a.copy() print(a) print(b) print(id(a)) print(id(b)) 结果: [1, 2, 3, 4] [1, 2, 3, 4] 28438088 29313096 结论: a列表的地址为28438088,b copy a后地址29313096,表明a复制b后创建了一个新的内存地址,这2个地址是完全独立的,等于我们现在有了2个杯子
2、接下来我们打印a、b列表中0索引位元素的地址值看看 print(id(a[0])) print(id(b[0])) print(id(a[1])) print(id(b[1])) 结果: 2079049664 2079049664 2079049648 2079049648 结论: 在列表中的每个元素的地址都是独立的 由此我们可以看出,虽然我们前面在1 中copy了一个新的列表地址,但是列表中每个单独的值地址却还是一样的,也就是说列表a和b虽然地址不一样,但列表中元素值指向的地址还是一致的。
3、改变列表a中索引位0的值为8 a = [1, 2, 3, 4, [5, 6], 7] b = a.copy() print(a) print(b) print(id(a[0])) print(id(a[0])) a[0] = 8 print(a) print(b) print(id(a[0])) print(id(b[0])) 结果: [1, 2, 3, 4, [5, 6], 7] [1, 2, 3, 4, [5, 6], 7] 2023606192 2023606192 [8, 2, 3, 4, [5, 6], 7] [1, 2, 3, 4, [5, 6], 7] 2023606304 2023606192 结论: 可以看出列表a索引位0的值指向了新的地址2023606304值为8,而列表b索引位0还是指向老的地址值2023606192值为1。
4、当列表中存在其他的列表时,会有什么不一样妮? a = [1, 2, 3, 4, [5, 6], 7] b = a.copy() a[4][0] = 8 print(a[4]) print(b[4]) print(id(a[4][0])) print(id(b[4][0])) 结果: [8, 6] [8, 6] 2079049760 2079049760 改变a列表索引位4上的二级列表中索引位0的值,我们可以看到b列表中二级列表索引0的值也一起被改变了!!!! 是不是很奇怪??? 按照我们前面说的,a的二级列表0应该指向了一个新地址,这个地址存储的值为8,b应该指向的是原来的老地址,值应该为5,但是现在b却也指向了新的地址,值显示也为8,和a的二级列表值一模一样,怎么会这样??? 同样的道理,列表中的子列表地址和其他列表元素一样也是一个独立的内存地址,而这个独立的子列表元素地址又指向了元素5和元素6, 元素5和元素6在子列表中的地址也是分别独立的,当我们改变子列表中索引位0的元素值为8后,子列表索引0就指向了存储元素8的新地址,因此我们会看到列表a和列表b的子列表元素值都发生了变化。
四、如果我们copy后想要完全独立的列表,我们可以这样: import copy a = [1, 2, 3, 4, [5, 6], 7] b = copy.deepcopy(a) print(a) print(b) print("------改变a的子列表0索引位元素-------") a[4][0] = 8 print(a) print(b) 结果: [1, 2, 3, 4, [5, 6], 7] [1, 2, 3, 4, [5, 6], 7] ------改变a的子列表0索引位元素------- [1, 2, 3, 4, [8, 6], 7] [1, 2, 3, 4, [5, 6], 7] 改变a子列表索引0元素值后,b子列表索引0元素值未改变 五、copy后子列表元素地址是不完全独立的copy就叫浅copy,copy后列表元素地址和子列表元素地址完全独立的copy就叫深copy
标签:列表,索引,地址,深浅,print,copy,id 来源: https://www.cnblogs.com/luohuasheng/p/16495122.html