python的浅拷贝与深拷贝

系统 1478 0

什么是浅拷贝?

先看一个例子

            
              a 
              
                =
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ,
              
              
                4
              
              
                ]
              
              
b 
              
                =
              
               a
a
              
                .
              
              pop
              
                (
              
              
                0
              
              
                )
              
              
                print
              
              
                (
              
              a
              
                )
              
              
                print
              
              
                (
              
              b
              
                )
              
            
          

输出:

            
              
                [
              
              2,3,4
              
                ]
              
              
                [
              
              2,3,4
              
                ]
              
            
          

正常对于这种可变对象的这种赋值,会导致 a和b指向一个内存地址,而我们将a中的第0个元素剔除后,实质就是改变了对应的内存地址中的数值,所以会导致b也发生变化
下面看一下浅拷贝:

            
              a 
              
                =
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ,
              
              
                4
              
              
                ]
              
              
b 
              
                =
              
               a
              
                .
              
              copy
              
                (
              
              
                )
              
              
a
              
                .
              
              pop
              
                (
              
              
                0
              
              
                )
              
              
                print
              
              
                (
              
              a
              
                )
              
              
                print
              
              
                (
              
              b
              
                )
              
            
          

输出

            
              
                [
              
              2,3,4
              
                ]
              
              
                [
              
              1,2,3,4
              
                ]
              
            
          

这种就是浅拷贝,拷贝的列表会单独存在另一块内存里面,所以修改原列表中的元素不影响新列表中的元素

什么是深拷贝?

看另一个例子

            
              a 
              
                =
              
              
                [
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ]
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ]
              
              
b 
              
                =
              
               a
              
                .
              
              copy
              
                (
              
              
                )
              
              
a
              
                [
              
              
                0
              
              
                ]
              
              
                .
              
              pop
              
                (
              
              
                0
              
              
                )
              
              
                print
              
              
                (
              
              a
              
                )
              
              
                print
              
              
                (
              
              b
              
                )
              
            
          

输出:

            
              
                [
              
              
                [
              
              2
              
                ]
              
              , 2, 3
              
                ]
              
              
                [
              
              
                [
              
              2
              
                ]
              
              , 2, 3
              
                ]
              
            
          

为什么我拷贝了原列表,新的列表还是随着原列表改变而改变了?
细心的人会发现,这种改变是改变了列表中的子元素中的内容,而不是只改变了列表
浅拷贝只是将被拷贝的元素存在单独一块内存,但是不能将拷贝元素中的子元素还单独存在一块内存

下面我们用深拷贝:

            
              
                import
              
               copy
a 
              
                =
              
              
                [
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ]
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ]
              
              
b 
              
                =
              
               copy
              
                .
              
              deepcopy
              
                (
              
              a
              
                )
              
              
a
              
                [
              
              
                0
              
              
                ]
              
              
                .
              
              pop
              
                (
              
              
                0
              
              
                )
              
              
                print
              
              
                (
              
              a
              
                )
              
              
                print
              
              
                (
              
              b
              
                )
              
            
          

输出:

            
              
                [
              
              
                [
              
              2
              
                ]
              
              , 2, 3
              
                ]
              
              
                [
              
              
                [
              
              1, 2
              
                ]
              
              , 2, 3
              
                ]
              
            
          

深拷贝不仅仅可以使被拷贝的对象存在单独一个地址中,而且被拷贝的子元素也单独存在一个地址中,是真正的完全拷贝

其他问题

列表中的不可变对象如:数字,字符串,元祖,这些使用深拷贝也会单独分配一块内存吗?由于这些是不可变对象,我们无法使用改变内存中的值来看到效果,但是我们可以通过 id() 这个函数来查看判断是否存储在同一块内存

            
              
                import
              
               copy
a 
              
                =
              
              
                [
              
              
                1
              
              
                ,
              
              
                2
              
              
                ,
              
              
                3
              
              
                ]
              
              
b 
              
                =
              
               copy
              
                .
              
              deepcopy
              
                (
              
              a
              
                )
              
              
                print
              
              
                (
              
              
                id
              
              
                (
              
              a
              
                [
              
              
                0
              
              
                ]
              
              
                )
              
              
                )
              
              
                print
              
              
                (
              
              
                id
              
              
                (
              
              b
              
                [
              
              
                0
              
              
                ]
              
              
                )
              
              
                )
              
            
          

输出:

            
              10914496
10914496

            
          

结果让人大跌眼睛,这个和我们预想不一样了
其实这是python内部做的优化,对于这些不可变对象,如果元素的值相同,python都会将他们存储在同一块内存以节约内存,因为这些是不可变对象,将他们存在同一块内存不会导致改变一个对象的值导致另一个对象值的变化,所以可以将他们存在同一块内存,这就是python中的inter机制


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论