说说python下的赋值,深拷贝与浅拷贝
本帖最后由 hijack 于 2017-6-14 19:28 编辑初学python的朋友一定会遇到过这个问题:n1=123
n2=n1
n1=456
n2=?
今天就针对这个问题详细说一说赋值,深拷贝与浅拷贝
python的深拷贝浅拷贝需要分两方面来说:字符串与数字类型;其他数据类型
首先看看字符串与数字类型:
对于字符串与数字类型:赋值,深拷贝,浅拷贝都是一回事儿,不用区别import copy
# 数字、字符串
n1 = 123
print(id(n1)) #id方法的返回值就是对象的内存地址
n2 = n1 #这是赋值
print(id(n2))
n3 = copy.copy(n1) #这是浅拷贝
print(id(n3))
n4 = copy.deepcopy(n1) #这是深拷贝
print(id(n3))
我们来查看下n1,n2,n3,n4的内存地址,如下图
对于字符串和数字来说,都一样,都是返回同一个内存地址,我们再来看看其他数据类型:
1、赋值,就是再创建个变量,指向原来内存地址n1 = {"k1": "hi", "k2": 123, "k3": ["hijack", 678]}
n2 = n1
此时的id(n1)=id(n2)和上面字符串一样
2、浅拷贝
浅拷贝,顾名思义,很浅呐,那么就是只是在内存中只额外创建第一层数据import copy
n1 = {"k1": "hi", "k2": 123, "k3": ["hijack", 678]}
n2 = copy.copy(n1)
print(id(n1),id(n2))
我们来看看内存地址
和赋值不同,浅拷贝的内存地址并不相同,看看图解释下
看看,是不是很浅,只创建第一层
3、深拷贝
深拷贝,顾名思义,很深呐,深到什么程度?深到除了最后一层,其余都重新创建一份(python内部对字符串和数字的优化)import copy
n1 = {"k1": "hi", "k2": 123, "k3": ["hijack", 678]}
n2 = copy.deepcopy(n1)
print(id(n1),id(n2))
同样n1和n2指向的内存地址肯定不一样,看看画图解释:
以上就是一些关于赋值,深拷贝浅拷贝的知识了,说的有什么不周到的还请多多指正
如果觉得觉得这篇文章对你有一点点作用的话,还请给个免费评分
楼主说得已经很好了。下面,我自己补充点吧!
1,浅拷贝,没有拷贝到子对象。所以原始数据改变,没有被拷贝到的子对象会改变
i1={'k3': ['hijack', 678], 'k2': 123, 'k1': 'hi'}
import copy
i2=copy.copy(i1)
i3=copy.deepcopy(i1)
现在改变原数据(最外层的),因为深拷贝和浅拷贝都涉及到了这一层,所以这一层的数据改变,不会影响拷贝的内容
>>> i1["k4"]="add_data_test"
>>> i2
{'k3': ['hijack', 678], 'k2': 123, 'k1': 'hi'}
>>> i3
{'k3': ['hijack', 678], 'k2': 123, 'k1': 'hi'}
>>> i1
{'k3': ['hijack', 678], 'k2': 123, 'k1': 'hi', 'k4': 'add_data_test'}
现在改变原数据(最内层的),因为深拷贝没有涉及到这一层,所以浅拷贝的结果会受到影响,而深拷贝的话,里面的对象也是被拷贝了的,所以值不会被改变
>>> i1["k3"].append("k3_test")
>>> i1
{'k3': ['hijack', 678, 'k3_test'], 'k2': 123, 'k1': 'hi', 'k4': 'add_data_test'}
>>> i2
{'k3': ['hijack', 678, 'k3_test'], 'k2': 123, 'k1': 'hi'}
>>> i3
{'k3': ['hijack', 678], 'k2': 123, 'k1': 'hi'}
>>>
总结:copy.copy()这个方法得到的对象是新对象,但是数据还是引用。
如果要完全得到一个新的一模一样的对象,要用copy.deepcopy()方法。这样,在改变新对象的时候,原对象才能不受影响,也就是保持原始数据不变
夏雨微凉 发表于 2017-6-14 21:23
这么说的话 python里边的变量是指针变量?比如 n2=n1,那么n1内容变了n2也会跟着变?
不会的,如果n1内容变了,比如变成n1=666,会另外出来一个内存地址装666,n1指向666的地址,n2还是指向原来的地址 {:1_912:}
python用的不多,希望看到你更多 的作品。
谢谢分享。 这么说的话 python里边的变量是指针变量?比如 n2=n1,那么n1内容变了n2也会跟着变? LZ这里有些时候可能要解释一下小整数缓冲区和字符串缓冲区会更好 前排留名。膜败:victory: 有种说法是“传值类型与传址类型”,跟这个说的一样吧 hijack 发表于 2017-6-14 23:46
不会的,如果n1内容变了,比如变成n1=666,会另外出来一个内存地址装666,n1指向666的地址,n2还是指向原 ...
哦,原来是这样 谢谢分享。我也刚学 看图的话可以使用:http://pythontutor.com/ 可视化观看python内的对象方法。
页:
[1]
2