关于 Python 深拷贝与浅拷贝
Python的数据结构总体分为两类:
1、字符串和数字
2、列表、元组、字典等
一、字符串和数字
对于字符串和数字而言,赋值(=)、浅拷贝(copy)和深拷贝(deepcopy)其实都没有意义,因为它们都永远指向同一个内存地址。
>>> import copy>>> a1 = 100>>> id(a1)1426656816 # a1的内存地址# 赋值>>> a2 = a1>>> id(a2)1426656816# 浅拷贝>>> a3 = copy.copy(a1)>>> id(a3)1426656816# 深拷贝>>> a4 = copy.deepcopy(a1)>>> id(a4)1426656816如图:

二、列表、元组、字典等
对于列表、字典而言,进行赋值(=)、浅拷贝(copy)和深拷贝(deepcopy),其引起的变化是不一样的。
2.1、赋值(=)
names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]name2 = namesnames[1] = "Pear"print(names)print(name2)print("-----------------")names[3][1] = "Dog"print(names)print(name2)print(id(names))print(id(name2))# 输出['Angle', 'Pear', 'Athena', ['Banana', 'apple']]['Angle', 'Pear', 'Athena', ['Banana', 'apple']]-----------------['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]15043874065361504387406536# 可以看到names 的每一次变化,name2也会改变,因为他们的内存地址是一样的如图:

这和字符串和数字是不一样的,当我们定义 a =1 ,b = a ,改变a时,b是不会有变化的。列表和字典等会跟着变化,因为他们的内存地址是一样的。
a = 1b = a a = 100print(a)print(b)# 输出1001 2.2、浅拷贝(copy)
我们接下来看:
import copynames = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]name2 = copy.copy(names)names[1] = "宙斯"print(names, "names的内存地址是{}".format(id(names)))print(name2, "name2的内存地址是{}".format(id(name2)))names[3][1] = '苹果'print(names, id(names[3]))print(name2, id(name2[3]))# 输出['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是2306153560776['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是2306152155528['Angle', '宙斯', 'Athena', ['Banana', '苹果']] 2306153648968['Angle', 'Zous', 'Athena', ['Banana', '苹果']] 2306153648968# 这次我们不仅改变了最外层的列表的值,还改变了列表中一个列表的值。# 这次的结果是 里层的列表跟着做了改变我们通过打印的内存地址可以明显看出,整个外层列表的内存地址是不一样的,但是里层的列表内存地址是一致的。
如图:

总结:浅拷贝(copy.copy(x))只是将列表等数据类型的第一层copy了一下,内存地址改变了。但是对于里层的数据类型的内存地址没有改变。
2.3、深拷贝(deepcopy)
深拷贝(copy.deepcopy(x))其实就是重新开辟了一个新的内存地址,存储deepcopy后的数据,和原来数据的内存地址完全不一样了,包括里层数据类型的内存地址。
如图:
