您的位置:首页 > 游戏 > 游戏 > python的深拷贝(deep copy)和浅拷贝(shallow copy)

python的深拷贝(deep copy)和浅拷贝(shallow copy)

2024/11/16 9:08:31 来源:https://blog.csdn.net/dmf_fff/article/details/139609167  浏览:    关键词:python的深拷贝(deep copy)和浅拷贝(shallow copy)

1.可变对象和不可变对象

1.1 不可变对象和可变对象的定义

  • 不可变对象: 可以理解为在对象创建后(创建并分配了 ID(内存地址))的情况下,其内容无法修改。任何尝试修改其内容的操作都会创建一个新的对象
  • 可变对象: 在对象创建后,在不改变 ID 的情况下,其内容是可以修改的

1.2 常见的可变对象和不可变对象及其示例

1.2.1 可变对象

  • 常见可变对象
    • 列表(list)
    • 字典(dict)
    • 集合(set)
    • 自定义对象
  • 可变对象修改示例
    • 示例代码
      # 列表是可变的
      print("######### 列表测试 #########")
      my_list = [1, 2, 3]
      print(" 列表修改前的内容 == ", my_list)  # 输出: [1, 2, 3]
      print(" 列表修改前的id == ", id(my_list))
      my_list[0] = 10  # 修改第一个元素
      print(" 列表修改后的内容 == ", my_list)  # 输出: [10, 2, 3]
      print(" 列表修改后的id == ", id(my_list))# 字典是可变的
      print("######### 字典测试 #########")
      my_dict = {'a': 1, 'b': 2}
      print(" 字典修改前的内容 == ", my_dict)  # 输出: {'a': 1, 'b': 2}
      print(" 字典修改前的id == ", id(my_dict))
      my_dict['a'] = 10  # 修改键'a'的值
      print(" 字典修改后的内容 == ", my_dict)  # 输出: {'a': 10, 'b': 2}
      print(" 字典修改后的id == ", id(my_dict))
      
    • 运行输出
      ######### 列表测试 #########列表修改前的内容 ==  [1, 2, 3]列表修改前的id ==  2529155928448列表修改后的内容 ==  [10, 2, 3]列表修改后的id ==  2529155928448
      ######### 字典测试 #########字典修改前的内容 ==  {'a': 1, 'b': 2}字典修改前的id ==  2529156249664字典修改后的内容 ==  {'a': 10, 'b': 2}字典修改后的id ==  2529156249664
      

1.2.2 不可变对象

  • 常见不可变对象
    • 整数(int)
    • 浮点数(float)
    • 字符串(str)
    • 元组(tuple)
  • 不可变对象修改示例
    • 示例代码
      # 整数是不可变的
      print("######### 整数测试 #########")
      x = 5
      print(" 整数修改前的内容 == ", x)
      print(" 整数修改前的id == ", id(x))
      x = 10  # 这里实际上是创建了一个新的整数对象,而不是修改原来的整数对象
      print(" 整数修改后的内容 == ", x)
      print(" 整数修改后的id == ", id(x))# 字符串是不可变的
      print("######### 字符串测试 #########")
      my_str = "hello"
      print(" 字符串修改前的内容 == ", my_str)
      print(" 字符串修改前的id == ", id(my_str))
      my_str = "world"  # 这里也是创建了一个新的字符串对象,而不是修改原来的字符串
      print(" 字符串修改后的内容 == ", my_str)
      print(" 字符串修改后的id == ", id(my_str))
      
    • 运行输出
      ######### 整数测试 #########整数修改前的内容 ==  5整数修改前的id ==  140723914734136整数修改后的内容 ==  10整数修改后的id ==  140723914734296
      ######### 字符串测试 #########字符串修改前的内容 ==  hello字符串修改前的id ==  2174965650112字符串修改后的内容 ==  world字符串修改后的id ==  2174965650400
      

2. 浅拷贝(shallow copy)

2.1 浅拷贝定义

  • 浅拷贝 :仅拷贝 目标对象 ,对于 目标对象 所包含的子对象仅进行 引用
  • 仅拷贝 可变对象 ,因为 不可变对象 是不会改变的,所以对其进行拷贝是没有意义的,所以,对于 不可变对象 仅仅进行引用。
  • 浅拷贝 仅拷贝 目标对象 ,所以只有目标对象是可变对象和目标对象是不可变对象两种情况。

2.2 浅拷贝方法

  • 使用标准库的 copy模块copy函数
    import copy
    list1 = [1, 2, 3]
    list2 = copy.copy(list1)
    
  • 使用数据类型本身的构造器
    # 列表
    list1 = [1, 2, 3]
    list2 = list(list1)
    # 字典
    dict1 = {1: 'a', 2: 'b'}
    dict2 = dict(dict1)
    #集合
    set1 = {1, 2, 3}
    set2 = set(set1)
    
  • 使用切片操作符 - 适用于列表
    list1 = [1, 2, 3]
    list2 = list1[:]
    
  • 使用对象自带的copy方法
    dict1 = {1: [1, 2, 3], 2: 'b'}
    dict2 = dict1.copy()
    

2.3 浅拷贝可变对象的示例

  • 示例代码
    import copy
    print("########### original_list ###########")
    original_list = [("tuple_0", "tuple_1"), ["list_0", "list_1"], 3]
    print(" id(original_list) = ", id(original_list))
    print(" id(original_list[0]) = ", id(original_list[0]))
    print(" id(original_list[1]) = ", id(original_list[1]))
    print(" id(original_list[2)) = ", id(original_list[2]))
    print("########### shallow_copied_list ###########")
    shallow_copied_list = copy.copy(original_list)
    print(" id(shallow_copied_list) = ", id(shallow_copied_list))
    print(" id(shallow_copied_list[0]) = ", id(shallow_copied_list[0]))
    print(" id(shallow_copied_list[1]) = ", id(shallow_copied_list[1]))
    print(" id(shallow_copied_list[2)) = ", id(shallow_copied_list[2]))
  • 代码输出
    ########### original_list ###########id(original_list) =  2593492160896id(original_list[0]) =  2593494296576id(original_list[1]) =  2593492162752id(original_list[2)) =  140723918731768
    ########### shallow_copied_list ###########id(shallow_copied_list) =  2593494397824id(shallow_copied_list[0]) =  2593494296576id(shallow_copied_list[1]) =  2593492162752id(shallow_copied_list[2)) =  140723918731768
    

2.4 浅拷贝不可变对象的示例

  • 代码示例
    import copy
    print("########### original_tuple ###########")
    original_tuple = (("tuple_0", "tuple_1"), ["list_0", "list_1"], 3)
    print(" id(original_tuple) = ", id(original_tuple))
    print(" id(original_tuple[0]) = ", id(original_tuple[0]))
    print(" id(original_tuple[1]) = ", id(original_tuple[1]))
    print(" id(original_tuple[2)) = ", id(original_tuple[2]))
    print("########### shallow_copied_tuple ###########")
    shallow_copied_tuple = copy.copy(original_tuple)
    print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple))
    print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0]))
    print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1]))
    print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
    
  • 代码输出
    ########### original_tuple ###########id(original_tuple) =  2327690951808id(original_tuple[0]) =  2327690438656id(original_tuple[1]) =  2327688304832id(original_tuple[2)) =  140723918731768
    ########### shallow_copied_tuple ###########id(shallow_copied_tuple) =  2327690951808id(shallow_copied_tuple[0]) =  2327690438656id(shallow_copied_tuple[1]) =  2327688304832id(shallow_copied_tuple[2)) =  140723918731768
    

3. 深拷贝(deep copy)

3.1 深拷贝定义

  • 深拷贝: 递归拷贝 目标对象子对象
  • 仅拷贝 可变对象 ,因为 不可变对象 是不会改变的,所以对其进行拷贝是没有意义的,所以,对于 不可变对象 仅仅进行引用。

    注:如果 不可变对象 中包含 可变对象 ,则也要对这个 父不可变对象 进行拷贝。

  • 在递归拷贝过程中,只要 下级对象 中出现 可变对象, 则上级对象无论是 可变对象 还是 不可变对象 都要对其进行拷贝。对 下级 没有 可变对象 的不可变对象进行引用。

3.2 深拷贝方法

  • 使用标准库的 copy模块deepcopy 函数
    import copy
    original_list = [1, 2, [3, 4]]
    deep_copied_list = copy.deepcopy(original_list)
    

3.3 深拷贝示例1

  • 代码示例
    import copy
    print("########### original_tuple ###########")
    original_tuple = (("tuple_0", "tuple_1", (1, 2)), ("list_0", "list_1", [12, 13]), 3)
    print(" id(original_tuple) = ", id(original_tuple))
    print(" id(original_tuple[0]) = ", id(original_tuple[0]))
    print(" id(original_tuple[1]) = ", id(original_tuple[1]))
    print(" id(original_tuple[2)) = ", id(original_tuple[2]))
    print("########### shallow_copied_tuple ###########")
    shallow_copied_tuple = copy.deepcopy(original_tuple)
    print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple))
    print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0]))
    print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1]))
    print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
    
  • 代码输出
    ########### original_tuple ###########id(original_tuple) =  1933688192320id(original_tuple[0]) =  1933687798912id(original_tuple[1]) =  1933688291264id(original_tuple[2)) =  140723912702456
    ########### shallow_copied_tuple ###########id(shallow_copied_tuple) =  1933688316480id(shallow_copied_tuple[0]) =  1933687798912id(shallow_copied_tuple[1]) =  1933688318400id(shallow_copied_tuple[2)) =  140723912702456
    

3.4 深拷贝示例2

  • 代码示例

    import copy
    print("########### original_tuple ###########")
    original_tuple = (("tuple_0", "tuple_1", (1, 2)), ("list_0", "list_1", (12, 13)), 3)
    print(" id(original_tuple) = ", id(original_tuple))
    print(" id(original_tuple[0]) = ", id(original_tuple[0]))
    print(" id(original_tuple[1]) = ", id(original_tuple[1]))
    print(" id(original_tuple[2)) = ", id(original_tuple[2]))
    print("########### shallow_copied_tuple ###########")
    shallow_copied_tuple = copy.deepcopy(original_tuple)
    print(" id(shallow_copied_tuple) = ", id(shallow_copied_tuple))
    print(" id(shallow_copied_tuple[0]) = ", id(shallow_copied_tuple[0]))
    print(" id(shallow_copied_tuple[1]) = ", id(shallow_copied_tuple[1]))
    print(" id(shallow_copied_tuple[2)) = ", id(shallow_copied_tuple[2]))
    
  • 代码输出

    ########### original_tuple ###########id(original_tuple) =  1932263735232id(original_tuple[0]) =  1932263242880id(original_tuple[1]) =  1932263636288id(original_tuple[2)) =  140723912702456
    ########### shallow_copied_tuple ###########id(shallow_copied_tuple) =  1932263735232id(shallow_copied_tuple[0]) =  1932263242880id(shallow_copied_tuple[1]) =  1932263636288id(shallow_copied_tuple[2)) =  140723912702456
    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com