编程语言
首页 > 编程语言> > python之深浅拷贝

python之深浅拷贝

作者:互联网

python之深浅拷贝

文章目录

一、为什么要有深浅拷贝?

二、赋值操作

img

Copysource_list = ['aaaa', 1111, ['bbbb', 2222]]
new_list = source_list
# 观察1:源列表与新列表都是指向同一内存地址
print('-------------------------观察1---------------------------')
print(id(source_list), id(new_list))    # 2119311293696 2119311293696

# 修改不可变类型
source_list[0] = 'AAAA'
# 修改可变类型中的值
source_list[-1][-1] = 3333

# 观察2:只要有一个人的列表中的索引所对应的值的内存地址改变,则都改变
print('-------------------------观察2---------------------------')
print(id(source_list), id(new_list))    # 2119311293696 2119311293696
print(id(source_list[0]), id(new_list[0]))  # 2119312019888 2119312019888
print(id(source_list[-1][-1]), id(new_list[-1][-1]))    # 2119311395248 2119311395248

# 总结:
"""
赋值操作列表与新列表都是指向同一内存地址,2个列表中,只要有一个人的列表中的索引所对应的值的内存地址改变,则都改变
"""

三、浅拷贝

img

img

img

Copysource_list = ['egon', 'alex', [1, 2]]
new_list = source_list.copy()
# 观察1:对源列表copy以后,产生的新列表内存地址发生了改变,不再是同一个列表。而新列表与源列表中的可变不可变类型的值在没修改之前都是指向同一个值。
print('-------------------------观察1---------------------------')
print(new_list)     # ['egon', 'alex', [1, 2]]
print(id(source_list), id(new_list))
print(id(source_list[0]), id(source_list[1]), id(source_list[2]))
print(id(new_list[0]), id(new_list[1]), id(new_list[2]))

# 观察2:对源列表中不可变类型的值进行修改以后,对于不可变类型的值,都是产生新值,让源列表的索引指向新的内存地址,并不会影响新列表。
print('-------------------------观察2---------------------------')
source_list[0] = 'EGON'
source_list[1] = 'ALEX'
print(source_list)     # ['EGON', 'ALEX', [1, 2]]
print(id(source_list[0]), id(source_list[1]), id(source_list[2]))
print(id(new_list[0]), id(new_list[1]), id(new_list[2]))

# 观察3:对源列表中可变类型的值进行修改以后,对于可变类型,我们可以改变类型中包含的值,但这个可变容器本身内存地址不变。即新列表的索引仍然指向原来的内存地址,于是新列表也跟着受影响。
print('-------------------------观察3---------------------------')
print(id(source_list[2]), id(source_list[2][0]), id(source_list[2][1]))
print(id(new_list[2]), id(new_list[2][0]), id(new_list[2][1]))
source_list[-1][0] = 111
source_list[-1][1] = 222
print(new_list)
print(source_list)     # ['EGON', 'ALEX', [1, 2]]
print(id(source_list[2]), id(source_list[2][0]), id(source_list[2][1]))
print(id(new_list[2]), id(new_list[2][0]), id(new_list[2][1]))

# 总结
"""
1、对源列表copy以后,产生的新列表内存地址发生了改变,不再是同一个列表。而新列表与源列表中的可变不可变类型的值在没修改之前都是指向同一个值。
2、对源列表中不可变类型的值进行修改以后,对于不可变类型的值,都是产生新值,让源列表的索引指向新的内存地址,并不会影响新列表。
3、对源列表中可变类型的值进行修改以后,对于可变类型,我们可以改变类型中包含的值,但这个可变容器本身内存地址不变。即新列表的索引仍然指向原来的内存地址,于是新列表也跟着受影响。
"""
# 引申:综合观察2与观察3可以得出,想要copy得到新的列表与源列表的改操作完全独立开,必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深copy。

四、深拷贝

img

img

img

Copyimport copy
source_list = ['egon', 'alex', [1, 2]]
new_list = copy.deepcopy(source_list)

print(new_list)
print(id(source_list), id(new_list))

print('------------查看容器第一层------------')
print('     不可变         不可变           可变')
print(id(source_list[0]), id(source_list[1]), id(source_list[2]))
print(id(new_list[0]), id(new_list[1]), id(new_list[2]))

print('------------查看容器第二层------------')
print(id(source_list[2][0]), id(source_list[2][1]))
print(id(new_list[2][0]), id(new_list[2][1]))

# 修改容器第一层的值:修改不可变类型
source_list[0] = 'EOGN'
source_list[1] = 'ALEX'

# 修改容器第二层的值:修改可变类型
source_list[2][0] = 111
source_list[2][1] = 222

print('------修改以后,修改源列表,新列表所有值不会一起受影响-------')
print(source_list)
print(new_list)

五、深浅使用总结

标签:python,list,列表,source,深浅,print,new,拷贝,id
来源: https://blog.csdn.net/prigilm/article/details/118438646