Python 直接赋值、浅拷贝和深度拷贝解析
1、
b = a 直接赋值,是一种对象的引用(别名)(即变量所存的地址一样)。
a b保存的是同一地址,指向的是同一对对象。
#例1 lst1 = [["1",1],["2",2],["3",3]] lst2 = lst1 lst1.append(["4",4]) print(lst1,lst2) 输出: [['1', 1], ['2', 2], ['3', 3], ['4', 4]] [['1', 1], ['2', 2], ['3', 3], ['4', 4]] --------------------------------------------- lst1 = [["1",1],["2",2],["3",3]] lst2 = lst1 lst1[0] = ["0",0] print(lst1,lst2) 输出: [['0', 0], ['2', 2], ['3', 3]] [['0', 0], ['2', 2], ['3', 3]] #例2 lst3 = [1,2,3,4] lst4 = lst3 lst3.append(5) print(lst3,lst4) 输出: [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] #例3 lst1 = [["1",1],["2",2],["3",3]] lst2 = dict(lst1) //注意这里进行了dict(),所以lst2 接收的不是lst1对象的地址,而是dict()后的新的字典对象的地址。 lst1.append(["4",4]) #lst1[0] = ["0",0] print(lst1,lst2) 输出: [['1', 1], ['2', 2], ['3', 3], ['4', 4]] {'1': 1, '2': 2, '3': 3}
b = a.copy() 拷贝父对象,不会拷贝父对象的子对象(即引用子对象,子对象发生变化,那么b的子对象也会发生变化)。(拷贝意味着本变量和与原变量不存储同一地址,原变量发生变化,b变量不会发生变化。)
lst1 = [["1",1],["2",2],["3",3]] lst2 = lst1.copy() lst1.append(["4",4]) #父对象的修改 lst1[0][0] = "0" #子对象的修改 lst1[0][1] = 0 #子对象的修改 print(lst1,lst2) [['0', 0], ['2', 2], ['3', 3], ['4', 4]] [['0', 0], ['2', 2], ['3', 3]]
b = copy.deepcopy(a) 拷贝了父对象和子对象,即两个变量完全孤立,互不影响。
lst1 = [["1",1],["2",2],["3",3]] lst2 = copy.deepcopy(lst1) lst1.append(["4",4]) lst1[0][0]= "0" print(lst1,lst2) 输出: [['0', 1], ['2', 2], ['3', 3], ['4', 4]] [['1', 1], ['2', 2], ['3', 3]]
最后参考一篇文章的汇总对比:
import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷贝 d = copy.deepcopy(a) #对象拷贝,深拷贝 a.append(5) #修改对象a a[4].append('c') #修改对象a中的['a', 'b']数组对象 print( 'a = ', a ) print( 'b = ', b ) print( 'c = ', c ) print( 'd = ', d ) 输出: ('a = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5]) ('b = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5]) ('c = ', [1, 2, 3, 4, ['a', 'b', 'c']]) ('d = ', [1, 2, 3, 4, ['a', 'b']])
参考文章:https://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html