zoukankan      html  css  js  c++  java
  • 034 Python深浅拷贝

    一、引言

    在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用

    针对该列表l1=['a','b','c',['d','e','f']]一般有三种方法,分别为:拷贝(赋值)、浅拷贝、深拷贝

    注意:拷贝 / 浅拷贝 / 深拷贝 都是针对可变类型数据而言的

    1.1 可变 or 不可变

    id不变值可变,即在原值的基础上修改,则为可变数据类型;值变id也变,即重新申请一个空间放入新值,则为不可变数据类型。

    可变or不可变 数据类型
    可变 列表,字典,集合
    不可变 数字,字符串,元组

    二、拷贝

    当lt2为lt的拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化

    简单的赋值,既两个变量指向同一个内存地址

    lt = [1,2,3,[1,2,3]]
    lt1 = lt
    lt.append(1)
    
    print(lt,id(lt))
    for i in lt1:
        print(i,id(i))
    print()
    print(lt1,id(lt1))
    for i in lt:
        print(i,id(i))
    

    [1, 2, 3, [1, 2, 3], 1] 2625145561800
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3] 2625145561736
    1 140720359563920

    [1, 2, 3, [1, 2, 3], 1] 2625145561800
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3] 2625145561736
    1 140720359563920

    上述打印内容会发现,可变类型lt和lt1的地址相同。

    lt中的可变类型lt[-1]和lt1的可变类型lt1[-1]的地址也相同。

    三、浅拷贝

    浅拷贝:当lt2为lt的浅拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2不变化

    copy.copy() 可变数据的类型中的内置方法.copy()也是浅拷贝

    import copy
    lt = [1,2,3,[1,2,3]]
    lt1 = copy.copy(lt)
    lt[-1].append(1)
    lt.append(1)
    
    print(lt,id(lt))
    for i in lt1:
        print(i,id(i))
    print()
    print(lt1,id(lt1))
    for i in lt:
        print(i,id(i))
    

    [1, 2, 3, [1, 2, 3, 1], 1] 1730037789896
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3, 1] 1730319865992

    [1, 2, 3, [1, 2, 3, 1]] 1730319793928
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3, 1] 1730319865992
    1 140720359563920

    上述打印内容会发现,可变类型lt和lt1的地址并不相同。这代表这两个列表有着各自的内存空间

    但是可变类型lt和lt1中的可变类型,又有着相同的内存地址,表面他们指向同一块内存。

    既,更改lt中的可变类型lt[-1]内容,同样会影响lt1[-1]内容

    三、深拷贝

    深拷贝: 当lt2为lt的深拷贝对象时,lt内的可变类型变化,lt2不变化;lt内的不可变类型变化,lt2不变

    copy.deepcopy() 我个人理解,深拷贝就是值拷贝

    import copy
    lt = [1,2,3,[1,2,3]]
    lt1 = copy.deepcopy(lt)
    lt[-1].append(1)
    lt.append(1)
    
    print(lt,id(lt))
    for i in lt1:
        print(i,id(i))
    print()
    print(lt1,id(lt1))
    for i in lt:
        print(i,id(i))
    

    [1, 2, 3, [1, 2, 3, 1], 1] 1581432267400
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3] 1581461734280

    [1, 2, 3, [1, 2, 3]] 1581461779656
    1 140720359563920
    2 140720359563952
    3 140720359563984
    [1, 2, 3, 1] 1581432267464
    1 140720359563920

    上述打印内容会发现,无论是lt还是lt1的内存地址都不相同,并且其中的可变类型的内存地址也不相同。

    这表示,这两个变量没有任何关联,只是单纯的值拷贝,不会影响彼此

  • 相关阅读:
    天气预报 Web 服务
    安装IE8在控制面板里面删除之后进不去桌面,提示找不到IESetting.dll 解决办法(解决IE8卸载不了的问题,返回IE7 ,返回IE6),从IE8回到IE7的方法.
    提供股票的Web Sservices 接口
    vc中操作Xml使用CMarkup类
    不要埋怨空降兵了
    图像分割与描述
    [非常感人] 我还能再救一个!
    向汶川地震中死难者致哀
    关于dotNet加密工具
    不注册使用 .NET Reactor
  • 原文地址:https://www.cnblogs.com/XuChengNotes/p/11309574.html
Copyright © 2011-2022 走看看