查看变量值存储的地址: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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted on 2022-07-19 18:00  时光以北暮南城  阅读(30)  评论(0编辑  收藏  举报