Python赋值、浅复制和深复制
Python赋值、浅复制和深复制
首先我们需要知道赋值和浅复制的区别:
赋值和浅复制的区别
赋值,当一个对象赋值给另一个新的变量时,赋的其实是该对象在栈中的地址,该地址指向堆中的数据。即赋值后,两个对象指向的是堆中同一块内存空间。当任何一个对象发生某些改变时,另一个也会发生同样的改变。这里的两个对象其实就是两个引用。
而浅复制,它会创建一个新的对象,即会在堆内存区开辟一个新的内存区域,存储新的对象,但是新的对象内存的只是原对象内元素的引用。当原对象的数据都是不可变数据时,此时浅复制和深复制是一样的。若是原对象内有可变数据,那么也只是复制那个可变数据的引用。
所以二者的区别即,赋值只不过给那段内存数据多起了一个名字,但是东西还是一个东西。而浅复制是创造了一个新的对象,并复制了原对象中所有的引用。
浅复制和深复制的区别
浅复制上面已经说过了。
深复制,深复制也会创建一个新的对象,会在内存当中开辟一个新的空间,对于不可变数据和浅复制是一样的,但是对于可变数据,深复制会在堆内存中创建一个一模样的数据,并返回引用,此时两个可变数据的内容一模一样,但是内存地址并不一样。
所以二者的区别就在于可变数据的复制,浅复制复制之后可变数据和原来的可变数据是同一块内存,改变这个数据,二者都将改变。而深复制,两个对象无论怎么变化都不会有相互影响。
浅复制的6种方法(有些是针对列表的)
原数据a = [1, 2, 3]
b = a[:]
,这个操作其实就是列表的切片操作,但是比较特殊,因为切出来的就是自己b = list(a)
,这个操作针对的不仅仅是列表,a可以是别的可变为列表的数据b = a * 1
, 这个不做过多解释b = [x for x in a]
,这个就是做了一个遍历的操作,并把引用复制一遍,即浅复制了。b = a.copy()
,这个是列表自带的浅复制,同样字典也有(二者都是可变数据)b = copy.copy(a)
,这个就是借助copy模块里面的浅复制。
深复制的方法
b = copy.deepcopy(a)
, 这个也是借助copy模块,copy模块里面有个deepcopy方法,也就是深复制。
讲的多不如例子来的实在
赋值和浅复制的区别
import copy
a = [1, 2, 3, [4, 5]]
# 赋值
b = a
# 浅复制
c = a[:]
# 改变原数据
a[3].append(6)
a.append(7)
# 输出地址
print(id(a), id(b), id(c)) # 140212335295536 140212335295536 140212335367104
print(a)
print(b)
print(c)
b是赋值所以会和a一模一样,而c是浅复制,所以改变列表中的列表时c会跟着改变,但是增加一个元素时并不会跟着改变。
深复制和浅复制的区别
import copy
a = [1, 2, 3, [4, 5]]
# 浅复制
b = a[:]
# 深复制
c = copy.deepcopy(a)
# 改变原数据
a[3].append(6)
a.append(7)
# 输出地址
print(id(a), id(b), id(c)) # 140212335378752 140212335373280 140212335378912
print(a)
print(b)
print(c)
b是浅复制,会和上述的c相同,而此例子中的c是深复制,并不会有什么改变
使用所有的复制方法来一个
a = [1, 2, 3, [4, 5], "Hello"]
b = a # 赋值
# 浅复制
c = a[:]
d = list(a)
e = a * 1
f = [x for x in a]
g = a.copy()
h = copy.copy(a)
i = copy.deepcopy(a) # 深复制
# 改变
a[3].append(6)
a[4] = "World"
a.append(7)
# 输出
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
print(h)
print(i)
这个例子好好看看,思考思考吧。
以上就是全部内容,若有错误请直接打脸指正!!!