栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

可变与不可变的浅拷贝与深拷贝问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

可变与不可变的浅拷贝与深拷贝问题

python编程快速上手(持续更新中…) Python可变与不可变

指的是内存区域可变和不可变
可变:字典、列表
不可变:数字、字符串、元组

简单可变类型拷贝

浅复制:引用复制,并没有产生新的地址
如果拷贝对象,原对象和copy对象都指向一个内存空间,只拷贝父对象,不会拷贝对象的内部子对象

用法:copy.copy(变量)

深拷贝:会产生新的空间
如果拷贝对象和原对象不是指向一个内存空间,会拷贝父对象与子对象

用法:copy.deecopy(变量)

可变类型:浅拷贝也会产生新的内存空间,能够保持对立性
可变类型:深拷贝会产生新的内心空间,能够保持独立性

# 可变: 变量创建完成后,内存可以改变
# 列表和字典
import copy

def test():
    # 可变类型的 浅拷贝 也会产生新的空间,能够保持各自的独立性
    list1 = [1, 2, 3]
    print("list1 = ", list1, id(list1))

    # list3 = list1
    # list3.append(5)
    # print("list3 = ",list3,id(list3))
    # 拷贝:
    # 1、导入模块 copy
    # 2、调用方法
    #    copy(变量) 产生副本,浅拷贝
    list2 = copy.copy(list1)
    print("list2 = ", list2, id(list2))

    # 修改list1
    list1.append(5)
    print("list1 = ", list1, id(list1))
    print("list2 = ", list2, id(list2))





list1 = [1, 2, 3]
print("list1 = ", list1, id(list1))
#    deepcopy(变量) 产生副本,深拷贝

list2 = copy.deepcopy(list1)
print("list2 = ", list2, id(list2))

# 修改list2
list2.append(7)
print("list2 = ", list2, id(list2))
print("list1 = ", list1, id(list1))

# 总结:简单可变类型的深拷贝,会产生新的空间,能够保持的各自的独立性

复杂可变类型拷贝

浅拷贝:拷贝父对象,子对象不会拷贝

深拷贝:拷贝父对象,子对象会拷贝

import copy

def test():
    A = [1, 2, 3]
    B = [11, 22, 33]
    # [[1, 2, 3], [11, 22, 33]]
    C = [A, B]

    print("A = ", A, id(A))
    print("B = ", B, id(B))
    print("C = ", C, id(C))
    print("C[0] = ", C[0], id(C[0]))

    # 对复杂可变类型进行浅拷贝
    # D产生了新的空间
    D = copy.copy(C)
    print("D = ", D, id(D))
    print("D[0] = ", D[0], id(D[0]))

    # 修改A的
    A[0] = 10
    print("A = ", A, id(A))
    print("D[0] = ", D[0], id(D[0]))





A = [1, 2, 3]
B = [11, 22, 33]
# [[1, 2, 3], [11, 22, 33]]
C = [A, B]

print("A = ", A, id(A))
print("C = ", C, id(C))
# print("C[0] = ", C[0], id(C[0]))

# 对C做深拷贝
D = copy.deepcopy(C)
print("D = ", D, id(D))
print("D[0]=",id(D[0]),"C[0]=",id(C[0]),"A=",id(A))

A[0] = 10
print("A = ", A, id(A))
print("D[0] = ", D[0], id(D[0]))

简单不可变类型拷贝

浅拷贝等价于“=”

结论:深浅拷贝,副本有源指向同一个内存空间

import copy


def test_copy():
    # 简单不可变的元组
    tuple1 = (1, 2, 3)
    print("tuple1 = ", tuple1, id(tuple1))

    # 对简单不可变类型做浅拷贝
    # 等价于  tuple2 = tuple1
    tuple2 = copy.copy(tuple1)
    print("tuple2 = ", tuple2, id(tuple2))



# 简单不可变的元组
tuple1 = (1, 2, 3)
print("tuple1 = ", tuple1, id(tuple1))

# 等价于  tuple2 = tuple1
tuple2 = copy.deepcopy(tuple1)
print("tuple2 = ", tuple2, id(tuple2))

复杂不可变类型拷贝

浅拷贝:直接引用
深拷贝:看数据具体是可变还是不可变的,如果数据是可变的,会产生新的空间,保持数据的独立性

def test_copy():

    A = [1, 2, 3]
    B = [11, 22, 33]

    # 定义元组
    C = (A, B)
    print("C = ", C, id(C))
    # C[0] = [100,200,300]

    # 复杂不可变类型的浅拷贝
    #  D = C
    D = copy.copy(C)
    print("D = ", D, id(D))
    print("D[0]", id(D[0]), "C[0]", id(C[0]), "A", id(A))

    D[0][0] = 10  # D[0]==C[0]
    print("D = ", D, id(D))


A = [1, 2, 3]
B = [11, 22, 33]

# 定义元组
C = (A, B)
print("C = ", C, id(C))

# 对C做深拷贝
D = copy.deepcopy(C)
print("D = ", D, id(D))
print("D[0]", id(D[0]), "C[0]", id(C[0]), "A", id(A))
# D拷贝自C,也是不可变的,D[0] 是一个列表,是可变的,通过D[0][0] 修改值
# D[0] = [100,200,300]
D[0][0] = 10
print("D = ", D, id(D))
print("C = ", C, id(C))

切片拷贝与字典拷贝
  • 切片拷贝: 浅拷贝(如果是简单可变类型,底层会产生新的空间)
  • 字典拷贝: 浅拷贝
def test():
    #        0 1 2 3 4 5 6
    # 简单、可变   深拷贝
    list1 = [1, 2, 3, 4, 5, 6, 7]
    print("list1 = ", list1, id(list1))

    # 切片拷贝,地址不一样
    list2 = list1[:]
    print("list2 = ", list2, id(list2))


def test_2():

    A = [1,2,3]
    B = [11,22,33]

    C = (A,B)
    print("C = ",C,id(C))
    D = C[:]
    print("D = ",D,id(D))



dict1 = {"age":[1,2]}
print("dict1 = ",dict1, id(dict1))

dict2 = dict1.copy()
print("dict2 = ",dict2, id(dict2))
print("--"*20)
dict1['age'][0] = 100
print("dict1 = ",dict1, id(dict1))
print("dict2 = ",dict2, id(dict2))

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/308429.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号