点击上方“Python3X”,选择“置顶或者星标”
第一时间收到精彩推送!
Python Every Day, 第 8 天
拷贝说白了就是复制。对变量操作有赋值、拷贝等方法。他们之间是有区别的。
赋值
就是把一个对象的引用(在内存中的存储地址)和变量进行关联起来。可以通过id(对象) 查看其内存地址。
a = 'abc'b = a #print(id(a), id(b)) # 20636768 20636768
b = a #
print(id(a), id(b)) # 20636768 20636768
如上,将变量a 赋值给b。其实是将a和b都是指向了字符串abc的内存地址(a和b是同一个引用),可以通过id()函数发现他们的内存空间地址是一样的。
浅拷贝
拷贝对象并给其分配新的内存。但是只会拷贝父对象,也就是第一层数据(后面代码解释)
通过 变量.copy() 进行浅拷贝。
# 定义一个变量aa = ['a', 1, 'd', ['z', 'x', 'c']]# b 浅拷贝了ab = a.copy()print(a) # ['a', 1, 'd', ['z', 'x', 'c']]print(b) # ['a', 1, 'd', ['z', 'x', 'c']]# 打印各自的内存地址,发现各不相同。证明了浅拷贝会分配一个新的内存地址print(id(a)) # 2767408print(id(b)) # 121575744# 修改a中的第一个元素为'A'a[0] = 'A'print(a) # ['A', 1, 'd', ['z', 'x', 'c']]print(b) # ['a', 1, 'd', ['z', 'x', 'c']] 发现b并没有受影响# 修改第四个元素中的第一个元素,将z 修改成 Qa[3][1] = 'Q'print(a) # ['A', 1, 'd', ['z', 'Q', 'c']]print(b) # ['A', 1, 'd', ['z', 'Q', 'c']] 发现b也被修改了。why?print(id(a[3])) # 2766208print(id(b[3])) # 2766208
a = ['a', 1, 'd', ['z', 'x', 'c']]
# b 浅拷贝了a
b = a.copy()
print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
print(b) # ['a', 1, 'd', ['z', 'x', 'c']]
# 打印各自的内存地址,发现各不相同。证明了浅拷贝会分配一个新的内存地址
print(id(a)) # 2767408
print(id(b)) # 121575744
# 修改a中的第一个元素为'A'
a[0] = 'A'
print(a) # ['A', 1, 'd', ['z', 'x', 'c']]
print(b) # ['a', 1, 'd', ['z', 'x', 'c']] 发现b并没有受影响
# 修改第四个元素中的第一个元素,将z 修改成 Q
a[3][1] = 'Q'
print(a) # ['A', 1, 'd', ['z', 'Q', 'c']]
print(b) # ['A', 1, 'd', ['z', 'Q', 'c']] 发现b也被修改了。why?
print(id(a[3])) # 2766208
print(id(b[3])) # 2766208
如上修改a中的第一个元素。b不会被修改。但是修改 第四个元素中的第一个元素。b却被影响了。这就是前面说的浅拷贝只会拷贝第一层数据。
第二层['z', 'Q', 'c']并没有拷贝成功。
这个时候b中的['z', 'Q', 'c'] 的内存地址和a中的['z', 'Q', 'c']内存地址是一样的。 (浅拷贝只是把这个第二层的引用拷贝过来了。)。所以a中第二层的数据发生变化,b中的数据也会跟着变化。
可以通过id() 进行验证。
print(id(a[3])) # 2766208print(id(b[3])) # 2766208# 2766208
print(id(b[3])) # 2766208
深拷贝
深拷贝就是对对象的完全拷贝,不管你有多少层,数据都不会共享。
深拷贝需要引入copy模块。import copy
还是拿上面的数据我们进行演示。
import copya = ['a', 1, 'd', ['z', 'x', 'c']]b = copy.deepcopy(a)print(a) # ['a', 1, 'd', ['z', 'x', 'c']]print(a) # ['a', 1, 'd', ['z', 'x', 'c']]# 变量的内存空间地址print(id(a)) # 120265424print(id(b)) # 15809072print(a[-1])# 最后一个元素(['z', 'x', 'c'])的内存地址print(id(a[-1])) # 16171936print(id(b[-1])) # 120265344# 修改a[0] = 'A'a[3][0] ='Q'print(a) # ['A', 1, 'd', ['Q', 'x', 'c']]# 深拷贝中第二层数据也是独立的,不会被修改print(b) # ['a', 1, 'd', ['z', 'x', 'c']]
a = ['a', 1, 'd', ['z', 'x', 'c']]
b = copy.deepcopy(a)
print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
print(a) # ['a', 1, 'd', ['z', 'x', 'c']]
# 变量的内存空间地址
print(id(a)) # 120265424
print(id(b)) # 15809072
print(a[-1])
# 最后一个元素(['z', 'x', 'c'])的内存地址
print(id(a[-1])) # 16171936
print(id(b[-1])) # 120265344
# 修改
a[0] = 'A'
a[3][0] ='Q'
print(a) # ['A', 1, 'd', ['Q', 'x', 'c']]
# 深拷贝中第二层数据也是独立的,不会被修改
print(b) # ['a', 1, 'd', ['z', 'x', 'c']]
往期Python Every Day
[每日一题]3、Python实现删除list中重复元素的几种方式
[每日一题]2、Python中的类的定义和装饰器@classmethod与@staticmethod
感谢您的阅读