一、浅拷贝
浅copy:是把原列表第一层的内存地址不加区分(不区分可变类型还是不可变类型)完全copy一份给新列表。
不可变类型:值发生改变时,内存地址也发生改变,即id也变,证明是没有在改变原值,是产生了新的值,如字符串,整形,浮点型,元组。
可变数据类型:值发生改变时,内存地址不变,即id不变,证明在改变原值,如列表,字典,集合。
list1=[ '狄仁杰', 18, [1,2] ]
注意 list2 =list1 这不叫拷贝,只能说list2与list1 指向了相同的内存地址
```go >>> list1=["狄仁杰",18,[1,2]] >>> list2=list1.copy() # 浅拷贝 >>> print(id(list1)) 16 >>> print(id(list2)) 44 >>> >>> print(id(list1[0]),id(list1[1]),id(list1[2])) 76 9328 20 >>> print(id(list2[0]),id(list2[1]),id(list2[2])) 76 9328 20 >>> # 可见浅拷贝只拷贝第一层的内存地址,第一层的内存地址与旧列表指向相同的内存空间
修改操作对浅拷贝的影响:
list1=[ '狄仁杰', 18, [1,2] ] list2=list1.copy() >>> list1[0]="孙尚香" >>> list1[2][0]=333 # 修改嵌套列表第一个元素 >>> list1[2][1]="张良" # 修改嵌套列表第二个元素 > >>> list1 ['孙尚香', 18, [333, '张良']] >>> list2 ['狄仁杰', 18, [333, '张良']] >>>
1.对于不可变类型新的赋值,都是产生了新值,让原列表的索引指向新的内存地址,并不会影响新列表。
2.对于可变类型,我们可以改变可变类型中包含的值,但内存地址不变, 即原列表的索引指向仍然指向原来的内存地址,于是新列表也跟着一起受影响`
list1=["狄仁杰",18,[1,2]] list2=list1.copy() list1[2][0]=111 list1[2][1]=222 print(list1) # ['egon', 'lxx', [111, 222]] print(list3) # ['egon', 'lxx', [111, 222]]
二、深拷贝
要想copy得到的新列表与原列表的改操作完全独立开必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深copy
>>> list1=["狄仁杰",18,[1,2]] >>> import copy >>> list4=copy.deepcopy(list1) >>> list1 ["狄仁杰",18,[1,2]] >>> list4 ['狄仁杰', 18, [1,2]] >>> hex(id(list1)) # list1的内存地址 '0x1adae' >>> hex(id(list4)) # list4的内存地址 '0x1adae2284c0' # 不可变 不可变 可变 print(hex(id(list1[0])), hex(id(list1[1])), hex(id(list1[2]))) print(hex(id(list3[0])), hex(id(list3[1])), hex(id(list3[2]))) ''' 0x1adae1cb090 0x7ffe4f8508c0 0x1adae0e0e40 0x1adae1cb090 0x7ffe4f8508c0 0x20aa32ad6c0 ''' 可见,对于不可变类型,深拷贝的列表地址指向与原列表相同,对于可变类型,深拷贝会重新开辟内存空间
修改操作对深拷贝的影响:
>>> list1=['狄仁杰',18,[1,2]] >>> import copy >>> list4=copy.deepcopy(list1) # 深拷贝 >>> list1 ['狄仁杰',18,[1,2]] >>> list4 ['狄仁杰',18,[1,2]] >>> list1[0]="孙尚香" # 修改list1 0号元素 >>> list1[2][0]=333 # 修改list1 2号元素即嵌套列表的0号元素 >>> list1[2][1]="张良" # 修改list1 2号元素即嵌套列表的1号元素 >>> list1 ['孙尚香', 18, [333, '张良']] >>> list4 ['狄仁杰', 18, [1, 2]] >>> >>>> hex(id(list1[2][0])) '0x274a2de79d0' >>> hex(id(list1[2][1])) '0x274a2f25d50' 可见修改list1后并没有影响到list4
不可变类型(字符串、元组)没有浅拷贝(因为压根就没有改的必要),有深拷贝。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234031.html原文链接:https://javaforall.net