Python的赋值,深拷贝和浅拷贝的区别
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
一般有三种方法,
alist=[1,2,3,[\'a\',\'b\']]
(1)直接赋值,传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变
alist = [1,2,3,[\'a\',\'b\']] b = alist print(b) #[1, 2, 3, [\'a\', \'b\']] alist.append(5) print(alist),print(b) #[1, 2, 3, [\'a\', \'b\'], 5] #[1, 2, 3, [\'a\', \'b\'], 5]
(2)copy浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
alist=[1, 2, 3, [\'a\', \'b\'], 5]
import copy c = copy.copy(alist) print(alist),print(c) #[1, 2, 3, [\'a\', \'b\'], 5] #[1, 2, 3, [\'a\', \'b\'], 5] alist.append(6) print(alist),print(c) #[1, 2, 3, [\'a\', \'b\'], 5,6] #[1, 2, 3, [\'a\', \'b\'], 5] alist.append(\'Python\') print(alist),print(c) #[1, 2, 3, [\'a\', \'b\'], 5,6,\'Python\'] #[1, 2, 3, [\'a\', \'b\'], 5] print(alist[3]) #[\'a\', \'b\'] alist[3].append(\'Python\') print(alist),print(c) #[1, 2, 3, [\'a\', \'b\', \'Python\'], 5, 6, \'Python\'] #[1, 2, 3, [\'a\', \'b\', \'Python\'], 5]
alist子对象被改变了
(3)深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
import copy alist = [1,2,3,[\'a\',\'b\']] d = copy.deepcopy(alist) print(alist),print(d) #[1, 2, 3, [\'a\', \'b\']] #[1, 2, 3, [\'a\', \'b\']] #没有改变 alist.append(5) print(alist),print(d) #[1, 2, 3, [\'a\', \'b\'], 5] #[1, 2, 3, [\'a\', \'b\']] #没有改变 alist = [1,2,3,[\'a\',\'b\']] print(alist[3]) #[\'a\', \'b\'] alist[3].append(\'Python\') print(alist),print(d) #[1, 2, 3, [\'a\', \'b\', \'Python\']] #[1, 2, 3, [\'a\', \'b\']] #没有改变
总结:
1. 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。
2. 浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。
3. 深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。