python『学习之路02』浅析深复制和浅复制的区别 -- deepcopy and copy

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017/11/14 23:21
# @Author : mixiu26
import copy

name = ["$zhaoyihuan","7yanhan","Xuliangchen",["alla", "jack"],"#@$guanyu"]

'''
name2 = name.copy()
此方法等价于 ----- >> name2 = copy.copy[name]
print(name)
print(name2)

name[2] = ["寒冷"]
name[3][0] = "ALLA"
print(name) # ['$zhaoyihuan', '7yanhan', ['寒冷'], ['alla, jack'], '#@$guanyu'] --- >> name的值发生了改变
print(name2) # ['$zhaoyihuan', '7yanhan', 'Xuliangchen', ['alla, jack'], '#@$guanyu'] name2 的值没有受到影响

列表中可以嵌套列表,现在我们需要把alex 改写成大写:

['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']
['$zhaoyihuan', '7yanhan', 'Xuliangchen', ['ALLA', 'jack'], '#@$guanyu']
此刻我们得到的值是这样的,就是嵌套列表中name2的alex也发生了改变,这是为什么呢?
首先我们在copy字符串给name2时, name 和 name2他们虽然指向同一列表, 但是他们在内存中指向的地址是不一样的,所以当我们修改严涵的姓名时,对name2是没
有影响的但是当我们列表嵌入子列表['alla', 'jack']时,然后再去修改alla的值时,name中的alle值也发生了改变,这是因为 ['alla', 'jack']这张列表从头到尾就
是这一份, 也说就是name 和 name2列表中元素 ['alla', 'jack'] 指向的内存地址值是一样的,虽然name2和name指向的内存地址不一样,但是他们嵌入的列表元素
指向的内存是一样的,所以不管你修改了他们当中哪一个变量中的alla, 另一个变量中的alla也会发生改变。

'''
'''
name2 = name
name[2] = ["寒冷"]
name[3][0] = "ALLA"
print(name) #['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']
print(name2) #['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']

当我们吧name的值直接赋值给name2时, 结果变成这样:
['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']
['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']

直接赋值和copy()和copy的区别:
name2 = name ------ >> 这里是直接把name在内存中的地址值直接赋值给name2,也就是说现在的栈内存有两个引用指向堆内存的同一地址
所以,此刻你再去修改name的元素, 必然会造成name2一起发生改变,因为他们在堆内存中的指向是一样的
name2 = name.copy() ---- >> 这里为什么说他们的内存指向不一样呢,因为name2 copy 的不是name的地址值,而是name在变量池中的指向
也就是说name --- >> 堆内存 ---- >> 指向变量池, name2 ---- >> 变量池, 所以, name2 的值虽然和name的值相同,但实际上他们是不一样的,
所以只要不涉及修改列表内共有元素的内存地址值,是相互不会影响的, 像['alla','jack']嵌入列表,读取的就是列表的内存地址值, 所以不管name
和 name2 谁修改了嵌入列表 ['ALLA', 'jack']), 都会导致它在内存中的值发生变化,从而导致name 和 name2同步变化。
'''
name2 = copy.deepcopy(name) # deepcopy --- >> 复制了name得值后开辟了自己的内存空间,name2指向新开的的内存地址,So,将来name的任何改变都不会再影响到name2.
name[2] = ["寒冷"] # ['$zhaoyihuan', '7yanhan', ['寒冷'], ['ALLA', 'jack'], '#@$guanyu']
name[3][0] = "ALLA" # ['$zhaoyihuan', '7yanhan', 'Xuliangchen', ['alla', 'jack'], '#@$guanyu']

print(name)
print(name2)
'''
由此, 建议不要轻易使用深copy, 数据会造成不必过多时会造成很大内存损耗。
'''
原文地址:https://www.cnblogs.com/mixiu26/p/7836650.html