zoukankan      html  css  js  c++  java
  • python中 =、copy、deepcopy的差别

    python2中,需要import copy模块

    python3中,直接可以使用copy()方法,但deepcopy()还是需要导入copy模块

    下面以python2为例:

    对于"=":

    #-*- coding:utf-8 -*-
    import copy
    l1=[1,[2,3]]
    l2=[1,[2,3]]
    l3=l1
    #查看l1、l2、l3各自的地址
    print id(l1),id(l2),id(l3) #139826875107232 139826875255192 139826875107232
    
    print id(l1[0]),id(l1[1]) #14786904 139677954645024
    print id(l2[0]),id(l2[1]) #14786904 139677954645024
    print id(l3[0]),id(l3[1]) #14786904 139677954645024
    l1[0]+=1
    l1[1].append(4)
    print id(l1[0]),id(l1[1]) #14786880 139677954645024
    print id(l2[0]),id(l2[1]) #14786904 139677954645024
    print id(l3[0]),id(l3[1]) #14786880 139677954645024
    
    print l1,l2,l3 #[2, [2, 3, 4]] [1, [2, 3]] [2, [2, 3, 4]]

    通过以上可以发现,利用=进行赋值的话,两个list是完全相同的,共享同一个地址上的list,对其中一个list进行任何操作,两个list都会变化。红色的地方表明,一开始所有的list都在同一地址,这是为什么,这里可以参考:python可变对象与不可变对象的差别

    对于“copy”:

    #-*- coding:utf-8 -*-
    import copy
    l1=[1,[2,3]]
    l2=copy.copy(l1)
    
    print id(l1),id(l2)#140244454279072 140244454426744
    print l1,l2 #[1, [2, 3]]         [1, [2, 3]]
    
    l1.append(3)
    print id(l1),id(l2)#140244454279072 140244454426744
    print l1,l2 #[1, [2, 3], 3]     [1, [2, 3]]
    
    l2.append(5)
    print id(l1),id(l2)#140244454279072 140244454426744
    print l1,l2 #[1, [2, 3], 3]    [1, [2, 3], 5]
    
    '''-------------------------------------------------------'''
    print id(l1[0]),id(l1[1]),id(l1[2])#28721496 140537829112864 28721448
    print id(l2[0]),id(l2[1]),id(l2[2])#28721496 140537829112864 28721400
    
    l1[1].append(4)
    print id(l1[0]),id(l1[1]),id(l1[2])#12296536 139992916270112 12296488
    print id(l2[0]),id(l2[1]),id(l2[2])#12296536 139992916270112 12296440
    print l1,l2 #[1, [2, 3, 4], 3]   [1, [2, 3, 4], 5]
    
    l2[1].remove(2)
    print id(l1[0]),id(l1[1]),id(l1[2])#41783640 140604104870944 41783592
    print id(l2[0]),id(l2[1]),id(l2[2])#41783640 140604104870944 41783544
    print l1,l2 #[1, [3, 4], 3]   [1, [3, 4], 5]
    
    l2.remove(1)
    print id(l1[0]),id(l1[1]),id(l1[2])#14700888 139644594265120 14700840
    print id(l2[0]),id(l2[1])#139644594265120 14700792
    print l1,l2 #[1, [3, 4], 3]   [[3, 4], 5]

    可以看到,一开始l2和l1的地址就是不相同的,但是一开始他们的子list,也就是l1[1]、l2[1]的地址一直是相同的,l2[1]与l1[1]会因为彼此变化而变化,也就是说,copy下,list的第一层不会因为彼此的改变而改变,但是子list还是会互相连动。

    对于"deepcopy":

    #-*- coding:utf-8 -*-
    import copy
    l1=[1,[2],[3,[4]]]
    l2=copy.deepcopy(l1)
    
    print l1,l2 #[1, [2], [3, [4]]]     [1, [2], [3, [4]]]
    print id(l1[0]),id(l1[1]),id(l1[2]) #42979672 140054670666784 140054670805184
    print id(l2[0]),id(l2[1]),id(l2[2]) #42979672 140054670805544 140054670805760
    
    l1[1].append(11)
    print l1,l2 #[1, [2, 11], [3, [4]]]     [1, [2], [3, [4]]]
    print id(l1[0]),id(l1[1]),id(l1[2]) #42979672 140054670666784 140054670805184
    print id(l2[0]),id(l2[1]),id(l2[2]) #42979672 140054670805544 140054670805760
    
    l1[2][1].append(11)
    print l1,l2 #[1, [2, 11], [3, [4, 11]]]     [1, [2], [3, [4]]]
    print id(l1[0]),id(l1[1]),id(l1[2]) #42979672 140054670666784 140054670805184
    print id(l2[0]),id(l2[1]),id(l2[2]) #42979672 140054670805544 140054670805760
    
    l2[2][1].append(11)
    print l1,l2 #[1, [2, 11], [3, [4, 11]]]     [1, [2], [3, [4, 11]]]
    print id(l1[0]),id(l1[1]),id(l1[2]) #42979672 140054670666784 140054670805184
    print id(l2[0]),id(l2[1]),id(l2[2]) #42979672 140054670805544 140054670805760

    可以发现,deepcopy下的两个list是完全不一样的两个list,互相的操作,互不影响。注意:这里可以看到,deepcopy是重新开辟了一块内存赋予给新的list,当数据很大会很占用内存。

  • 相关阅读:
    IoC容器设计
    乐观锁(Optimistic Lock)
    file,path,uri互相转换
    QGraphicsView的paintEvent双缓存绘画
    简单的串口通信程序控制光源
    Qt--QMdiArea和QMdiSubWindow的基本用法
    Qt--支持鼠标拖动来移动内容的QScrollArea视窗
    快速排序算法记录
    结构体在内存中的对齐规则
    求N个数的数组中第K大的数的值
  • 原文地址:https://www.cnblogs.com/ybf-yyj/p/9284548.html
Copyright © 2011-2022 走看看