Python中一切皆为对象,不管是集合变量还是数值型or字符串型的变量都是一个引用,都指向对应内存空间中的对象。
简而言之:
变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值相同,当一个发生变化时,另一个也随之变化。
变量浅拷贝:新变量本身与原变量指向不同的内存空间,但是新变量内部的元素与原变量指向相同的内存空间;当改变原变量内部的可变对象的值时,新变量内部的值也发生随之变化;改变原变量内部的不可变对象的值时,新变量内部的值不随之变化;反之亦然(即改变新变量时)。
变量深拷贝:新变量与原变量本身及其内部元素都指向不同的内存空间,改变原变量的值时,新变量中的值不会发生变化,反之亦然。
1. 不可变对象:int,float,long,str,tuple等;
1 In[20]: a = 1 2 In[21]: b = a 3 In[22]: id(a) 4 Out[22]: 33719592L 5 In[23]: id(b) 6 Out[23]: 33719592L 7 In[24]: a = 2 8 In[25]: id(a) 9 Out[25]: 33719568L 10 In[26]: id(b) 11 Out[26]: 33719592L 12 In[27]: b = 3 13 In[28]: id(b) 14 Out[28]: 33719544L
可以看出最开始a、b指向同一个内存空间,但是当改变a的值时,a指向了新的内存空间(此时b没有发生变化),改变b时b也指向了新的内存空间;类似于C语言中的值传递。
2. 可变对象:list,set,dict, array, matrix等
1 In[29]: list1 = [1,2,3] 2 In[30]: list2 = list1 3 In[31]: id(list1) 4 Out[31]: 61244552L 5 In[32]: id(list2) 6 Out[32]: 61244552L 7 In[33]: list1[0] = 101 8 In[34]: id(list1) 9 Out[34]: 61244552L 10 In[35]: id(list2) 11 Out[35]: 61244552L 12 In[36]: list1 13 Out[36]: [101, 2, 3] 14 In[37]: list2 15 Out[37]: [101, 2, 3] 16 In[38]: list2[1] = 102 17 In[39]: id(list1) 18 Out[39]: 61244552L 19 In[40]: id(list2) 20 Out[40]: 61244552L 21 In[41]: list1 22 Out[41]: [101, 102, 3] 23 In[42]: list2 24 Out[42]: [101, 102, 3]
刚开始list1和list2指向同一个内存空间,改变list1中的值时,list2也跟着改变,但是它们指向的内存空间没有发生变化;同样,改变list2中的值时,list1的值也跟着变化,它们仍然指向同一个内存空间。
浅拷贝和深拷贝:
1 import copy 2 a = [1,[1, 2, 3], [4, 5, 6]] 3 b = a 4 c = copy.copy(a) 5 d = copy.deepcopy(a) 7 a.append(15) 8 a[1][2] = 10 9 a[0] = 0 11 print a 12 print b 13 print c 14 print d 16 print id(a) 17 print id(b) 18 print id(c) 19 print id(d)
输出为:
1 [0, [1, 2, 10], [4, 5, 6]] 2 [0, [1, 2, 10], [4, 5, 6]] 3 [1, [1, 2, 10], [4, 5, 6]] 4 [1, [1, 2, 3], [4, 5, 6]] 5 38023496 6 38023496 7 36700104 8 38023368
1 print ‘a[1]‘,id(a[1]) 2 print ‘b[1]‘,id(b[1]) 3 print ‘c[1]‘,id(c[1]) 4 print ‘d[1]‘,id(d[1]),‘\n‘ 6 print ‘a[0]‘,id(a[0]) 7 print ‘b[0]‘,id(b[0]) 8 print ‘c[0]‘,id(c[0]) 9 print ‘d[0]‘,id(d[0])
输出为:
1 a[1] 39654856 2 b[1] 39654856 3 c[1] 39654856 4 d[1] 39704904 6 a[0] 34112864 7 b[0] 34112864 8 c[0] 34112834 9 d[0] 34112840
b和a指向同一个内存空间,改变a中的值,则b跟着改变。c是a浅拷贝,c指向和a不同的内存空间,但是如果a中有一个元素为可变对象,则c中的此元素和a中的元素指向同一个内存空间,则改变a中此可变对象里面的值时,c中的值也改变;改变a中不可变对象的元素的值时,c中的值不发生变化。d是a的深拷贝,d和a指向不同的内存空间,d内部的元素和a内部元素也指向不同的空间,改变a里面的值时,d不会发生变化。
简而言之:
变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值相同,当一个发生变化时,另一个也随之变化。
变量浅拷贝:新变量本身与原变量指向不同的内存空间,但是新变量内部的元素与原变量指向相同的内存空间;当改变原变量内部的可变对象的值时,新变量内部的值也发生随之变化;改变原变量内部的不可变对象的值时,新变量内部的值不随之变化;反之亦然(即改变新变量时)。
变量深拷贝:新变量与原变量本身及其内部元素都指向不同的内存空间,改变原变量的值时,新变量中的值不会发生变化,反之亦然。
参考:http://blog.csdn.net/u013573813/article/details/53349798