《Python面试每日一题》之深拷贝、浅拷贝

问题描述:

深拷贝和浅拷贝的区别是什么?

答:

深拷贝是将对象内容复制给另一个对象,在内存中再开辟一段新的空间。这意味着如果对对象的副本进行更改时不会影响原对象。使用copy模块的deepcopy函数可以深拷贝一个对象(详见实例代码2)。
当对象是非嵌套类型时,浅拷贝是将对象的引用复制给另一个对象,在内存中不开辟新的空间。因此,如果我们在副本中进行更改,则会影响原对象。例如:列表赋值、列表的切片等。使用copy模块的copy函数可以浅拷贝一个对象。
当对象是嵌套类型,且最顶层非元组类型时,浅拷贝该对象只在内存内开辟一段新的空间给最顶层,而对于非顶层的数据只是引用指向(详见实例代码1)

a = ["tomato1998","1998tomato","toma1998to"]
b = a
print("a的初始内容:",a)
print("b的初始内容:",b)
a.append("to1998mato")
print("a修改后a的内容:",a)
print("a修改后b的内容:",b)
print(id(a))
print(id(b))

运行结果是:

a的初始内容: ['tomato1998', '1998tomato', 'toma1998to']
b的初始内容: ['tomato1998', '1998tomato', 'toma1998to']
a修改后a的内容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
a修改后b的内容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
1672231092296
1672231092296

使用copy模块的deepcopy函数可以深拷贝一个对象,我们将上述代码修改为深拷贝。

import copy
a = ["tomato1998","1998tomato","toma1998to"]
b = copy.deepcopy(a)
print("a的初始内容:",a)
print("b的初始内容:",b)
a.append("to1998mato")
print("a修改后a的内容:",a)
print("a修改后b的内容:",b)
print(id(a))
print(id(b))

运行结果是:

a的初始内容: ['tomato1998', '1998tomato', 'toma1998to']
b的初始内容: ['tomato1998', '1998tomato', 'toma1998to']
a修改后a的内容: ['tomato1998', '1998tomato', 'toma1998to', 'to1998mato']
a修改后b的内容: ['tomato1998', '1998tomato', 'toma1998to']
2350861606664
2350861605640

需要注意的是,如果拷贝的对象是不可变类型(例如元组),那么无法对其进行深拷贝和浅拷贝,仅仅是指向。(详见实例代码3)
如果用copy或deepcopy对一个全部都是不可变类型的数据进行拷贝,那么此时仅仅是引用指向,无深拷贝和浅拷贝之说。
如果拷贝的是一个拥有不可变类型的数据,即使最顶层是元组类型,那么deepcopy依然是深拷贝,而copy还是引用指向。


实例代码1:

"""对嵌套类型对象浅拷贝"""
import copy
a = ["tomato2020",("tomato1988","tomato1998"),[11,22,33]]
b = copy.copy(a)
print("a的内存空间是:",id(a))
print("b的内存空间是:",id(b))
print("a的第一个元素内存空间是:",id(a[0]))
print("b的第一个元素内存空间是:",id(b[0]))
print("a的第二个元素内存空间是:",id(a[1]))
print("b的第二个元素内存空间是:",id(b[1]))
print("a的第三个元素内存空间是:",id(a[2]))
print("b的第三个元素内存空间是:",id(b[2]))

运行结果:

a的内存空间是: 2524633652488
b的内存空间是: 2524633718344
a的第一个元素内存空间是: 2524633623344
b的第一个元素内存空间是: 2524633623344
a的第二个元素内存空间是: 2524630539912
b的第二个元素内存空间是: 2524630539912
a的第三个元素内存空间是: 2524633657736
b的第三个元素内存空间是: 2524633657736

实例代码2

"""对嵌套类型对象深拷贝"""
a = ["tomato2020",("tomato1988","tomato1998"),[11,22,33]]
b = copy.deepcopy(a)
print("a的内存空间是:",id(a))
print("b的内存空间是:",id(b))
print("a的第一个元素内存空间是:",id(a[0]))
print("b的第一个元素内存空间是:",id(b[0]))
print("a的第二个元素内存空间是:",id(a[1]))
print("b的第二个元素内存空间是:",id(b[1]))
print("a的第三个元素内存空间是:",id(a[2]))
print("b的第三个元素内存空间是:",id(b[2]))

运行结果:

a的内存空间是: 3132883426568
b的内存空间是: 3132883492296
a的第一个元素内存空间是: 3132883397232
b的第一个元素内存空间是: 3132883397232
a的第二个元素内存空间是: 3132880313928
b的第二个元素内存空间是: 3132880313928
a的第三个元素内存空间是: 3132883431752
b的第三个元素内存空间是: 3132883492360

实例代码3:

"""对不可变类型数据深拷贝、浅拷贝"""
a = ("tomato1998","tomato2020",11)
b = copy.copy(a)
c = copy.deepcopy(a)
print("a的内存空间是:",id(a))
print("b的内存空间是:",id(b))
print("c的内存空间是:",id(c))

运行结果:

a的内存空间是: 1201743173240
b的内存空间是: 1201743173240
c的内存空间是: 1201743173240
发布了14 篇原创文章 · 获赞 9 · 访问量 3824

猜你喜欢

转载自blog.csdn.net/qq_43462005/article/details/104241238