美文网首页
py12浅拷贝和深拷贝的区别

py12浅拷贝和深拷贝的区别

作者: 阿登20 | 来源:发表于2020-07-25 02:19 被阅读0次
    赋值这种操作,如果是不可变类型,修改不会互相影响。如果是可变类型,修改会互相影响,因为是指向的同一个内存地址,1个变了,另外一个也会变。
    
    浅拷贝:不管是可变类型还是不可变类型,都是一一复制。嵌套的是可变类型,修改会互相影响。
    
    深拷贝:嵌套的可变类型重新创建一份,这样和原来的嵌套可变类型互不影响。不可变类型还是用之前的。如果不可变类型修改,是重新指向新的地址,原来的指向不变。
    
    

    浅拷贝和深拷贝

    一、通过赋值

    1.不可变类型

    • 不可变类型变量a赋值给另外一个变量b。a,b改变互不影响
    # 不可变类型,变量a赋值给b.一方百变另一方不改变。互不影响
    a = "阿登"
    b = a
    print(a, type(a),id(a))
    print(b, type(b),id(b))
    
    print("---".center(50, "-"))
    b = "向佳"
    
    print(a, type(a),id(a))
    print(b, type(b),id(b))
    结果:
    
    阿登 <class 'str'> 6376944
    阿登 <class 'str'> 6376944
    -----------------------------------
    阿登 <class 'str'> 6376944
    向佳 <class 'str'> 31573248
    
    • 画图理解
    image.png
    • 可变类型变量a赋值给另外一个变量b。a,b改变,互相影响
    # 可变类型a,通过赋值给b。一方改变,另一个也会改变
    one_list = [1,2,[3,4]]
    two_list = one_list
    print(one_list,id(one_list))
    print(two_list,id(two_list))
    print("---------------------")
    two_list[0] = 5
    
    print(one_list,id(one_list))
    print(two_list,id(two_list))
    结果:
    [1, 2, [3, 4]] 42912264
    [1, 2, [3, 4]] 42912264
    ---------------------
    [5, 2, [3, 4]] 42912264
    [5, 2, [3, 4]] 42912264
    

    二、浅拷贝

    • from copy import copy

    • 浅拷贝拷贝的是第一层,元素都是不可变类型,修改里面的元素。原来的不会改变

    • 浅拷贝如果元素是可变类型,修改可变类型内的元素,原来的可变类型中的元素也会跟着改变

    from copy import copy,deepcopy
    list1 = [["a","b"],1]
    list2 = copy(list1)
    print(list1,type(list1), id(list1))
    print(list2,type(list2), id(list2))
    
    list2[0][0] = "c"
    print("---".center(50, "-"))
    print(list1,type(list1), id(list1))
    print(list2,type(list2), id(list2))
    结果:
    [['a', 'b'], 1] <class 'list'> 35682440
    [['a', 'b'], 1] <class 'list'> 35681224
    --------------------------------------------------
    [['c', 'b'], 1] <class 'list'> 35682440
    [['c', 'b'], 1] <class 'list'> 35681224
    # 可以看出list1和list2 索引为0的列表里的第一个元素被修改成了'c' .
    
    image.png

    三、深拷贝

    • 浅拷贝是把第一层内存地址不加区分一一复制一份。嵌套的可变类型不加一区分,考的内存地址是原来的所以啊你改变嵌套的可变类型的元素,原来的可变嵌套里的元素也变了。
    • 深拷贝:将嵌套的可变类型在内存中重新创建一份,而不可变类型还是用之前的。
    list1 = [["a","b"],1]
    list2 = deepcopy(list1)
    print(f"list1嵌套列表的id:{id(list1[0])}--{id(list1[1])}")
    print(f"list2嵌套列表的id:{id(list2[0])}--{id(list2[1])}")
    print("---".center(50, "-"))
    print("嵌套可变第一个元素地址{}\n嵌套可变第2个元素地址{}\n不可变元素地址{}".format(id(list1[0][0]),id(list1[0][1]),id(list1[1])))
    print("嵌套可变第一个深拷贝元素地址{}\n嵌套可变深拷贝第2个元素地址{}\n不可变深拷贝元素地址{}".format(id(list2[0][0]),id(list2[0][1]),id(list2[1])))
    
    print(list1,type(list1), id(list1))
    print(list2,type(list2), id(list2))
    
    print()
    list2[0][0] = "c"
    list2[1] = 2
    print("list2修改嵌套列表第一个元素为c".center(50, "-"))
    print(f"list1嵌套列表的id:{id(list1[0])}--{id(list1[1])}")
    print(f"list2嵌套列表的id:{id(list2[0])}--{id(list2[1])}")
    print()
    print("---".center(50, "-"))
    print("嵌套可变第一个元素地址{}\n嵌套可变第2个元素地址{}\n不可变元素地址{}".format(id(list1[0][0]),id(list1[0][1]),id(list1[1])))
    print("嵌套可变第一个深拷贝元素地址{}\n嵌套可变深拷贝第2个元素地址{}\n不可变深拷贝元素地址{}".format(id(list2[0][0]),id(list2[0][1]),id(list2[1])))
    print(list1,type(list1), id(list1))
    print(list2,type(list2), id(list2))
    
    image.png
    list1嵌套列表的id:42982152--8791146423120
    list2嵌套列表的id:42982472--8791146423120
    --------------------------------------------------
    嵌套可变第一个元素地址34327160
    嵌套可变第2个元素地址34325480
    不可变元素地址8791146423120
    嵌套可变第一个深拷贝元素地址34327160
    嵌套可变深拷贝第2个元素地址34325480
    不可变深拷贝元素地址8791146423120
    [['a', 'b'], 1] <class 'list'> 42863368
    [['a', 'b'], 1] <class 'list'> 42862152
    
    ----------------list2修改嵌套列表第一个元素为c----------------
    list1嵌套列表的id:42982152--8791146423120
    list2嵌套列表的id:42982472--8791146423152
    
    --------------------------------------------------
    嵌套可变第一个元素地址34327160
    嵌套可变第2个元素地址34325480
    不可变元素地址8791146423120
    嵌套可变第一个深拷贝元素地址6069192
    嵌套可变深拷贝第2个元素地址34325480
    不可变深拷贝元素地址8791146423152
    [['a', 'b'], 1] <class 'list'> 42863368
    [['c', 'b'], 2] <class 'list'> 42862152
    

    总结:

    赋值这种操作,如果是不可变类型,修改不会互相影响。如果是可变类型,修改会互相影响,因为是指向的同一个内存地址,1个变了,另外一个也会变。

    浅拷贝:不管是可变类型还是不可变类型,都是一一复制。嵌套的是可变类型,修改会互相影响。

    深拷贝:嵌套的可变类型重新创建一份,这样和原来的嵌套可变类型互不影响。不可变类型还是用之前的。如果不可变类型修改,是重新指向新的地址,原来的指向不变。

    相关文章

      网友评论

          本文标题:py12浅拷贝和深拷贝的区别

          本文链接:https://www.haomeiwen.com/subject/wgoylktx.html