'''
预备知识 :
数据在内存中的具体存储方式 : 内存是由一个又一个字节组成,而每一个字节都有一个唯一的地址,而数据在内存中即是从地址大的字节开始存储,也即内存寻址从大到小,
以lst = [3,2,3,2,1],假定一个整数在内存中占用两个字节,在内存中的存储为例,具体如下 :
'''
地址 | 变量 | 值 |
0xffffffff001 |
|
|
0xffffffff002 |
|
|
0xffffffff003 | lst[0]
| 3 |
0xffffffff004 |
0xffffffff005 | lst[1] | 2 |
0xffffffff006 |
0xffffffff007 | lst[2] | 3 |
0xffffffff008 |
0xffffffff009 | lst[3]
| 2 |
0xffffffff010 |
0xffffffff011 | lst[4] | 1 |
0xffffffff012 |
'''
当在结构性数据中又嵌套一个结构性数据时,如在列表中有嵌套一个列表,
以lst = [3, 2, [4, 3, 2], 4]为例说明其在内存中的存储方式 :
'''
地址 | 变量 | 值 |
0xffffffff001 |
|
|
0xffffffff002 |
|
|
0xffffffff003 |
|
|
0xffffffff004 |
|
|
0xffffffff005 | lst[0] | 3 |
0xffffffff006 |
0xffffffff007 | lst[1] | 2 |
0xffffffff008 |
0xffffffff009 | lst[2]
| 0xfffffffff07 |
0xffffffff010 |
0xffffffff011 | lst[3] | 4 |
0xffffffff012
|
'''
当代码执行至lst[2]分配内存空间时,又会开辟一块新的内存空间分配给lst[2]如下:
'''
地址 | 变量 | 值 |
0xfffffffff01 |
|
|
0xfffffffff02 |
|
|
0xfffffffff03 |
|
|
0xfffffffff04 |
|
|
0xfffffffff05 |
|
|
0xfffffffff06 |
|
|
0xfffffffff07 | lst[2][0] | 4 |
0xfffffffff08 |
0xfffffffff09 | lst[2][1]
| 3 |
0xfffffffff10 |
0xfffffffff11 | lst[3][2] | 2 |
0xfffffffff12
|
'''
为lst[2]分配完内存空间后,将lst[2]的地址,也即所谓内存空间的最小地址,存入lst[2]在lst中位置,以指向lst[2]在内存的存储位置
'''
'''
浅拷贝 : 即只复制目标对象,但不复制与目标对象有关的对象,如 :
方式一 :
lst = [3, 2, [4, 3, 2], 4]
lst1 = lst[ : ] #执行此时,会为lst1开辟一块新的内存空间,并将上文中的第一块内存空间里的内容复制到新的内存空间中,但并不会为lst1复制一份新的上文中的第二块内存空间,
也即此时lst和lst1共用上文中的第二个表格代表的内存空间,此时,如果修改上文中第二块内存空间中的值,lst和lst1中的值会跟着一起改变
方式二 :
lst1 = lst.copy() #同样是一种浅拷贝方式
#注 : lst1 = lst 与浅拷贝不同,赋值是直接将lst的在内存中的地址赋值给lst1,类似于小数据池
深拷贝 : 将目标对象及与目标对象相关的所有对象全部都复制一份
import copy
lst1 = copy.deepcopy(lst)
'''
'''
数据结构的死循环 :
如 : a = [1, 2]
a[1] = a
print(a[1])
结果 : [1, [1, [1, [1 ,[.......]]]]] #之所以出现这种现象是由于只要在某一个构造性数据中出现地址,系统就会自动将地址指向的内容替换该地址并打印出来,由此造成了上述循环往复的现象
'''