首页 > 其他分享 >浅拷贝与深拷贝

浅拷贝与深拷贝

时间:2023-08-20 11:22:24浏览次数:19  
标签:对象 list 内存 拷贝 copy id

From: B座17楼 2022-06-23 10:12 发表于重庆

--------------------------------------------------------------

  1. copy() 深浅的区别

doesn’t always really copy 并不总是复制要复制一个 list 或 dict,可以写 my_list.copy() 或 my_dict.copy()到此为止,一切顺利。但是,如果你认为对原始版本的更改不会影响到副本,那么遗憾地告诉你,错了。copy()会创建一个新的列表,但列表中的每个 dict 都是对原始列表中同一对象的引用。下图显示了对 list-of-dicts 进行浅复制和深复制(真正进行复制)的区别。

from copy import deepcopy

my_list = [{"one": 1}]

# # 创建两个地址并不同的副本
shallow_copy = my_list.copy()
deep_copy = deepcopy(my_list)

# 更改原始数据
my_list.append({"two": 2})
my_list[0]["one"] = 77 

# 查看更改
assert my_list == [{"one": 77}, {"two": 2}]
assert shallow_copy == [{"one": 77}]  # Mutated!
assert deep_copy == [{"one": 1}]

------------------------------------------------------

赋值,浅拷贝,还是深拷贝?

一个关于Python内存管理的故事

from copy import copy, deepcopy

这篇文章的目的是描述当我们在内存中发生什么时

赋值一个变量B = A 。

浅层拷贝它 C = copy(A) , 或

深度拷贝 D = deepcopy(A)。

我首先描述了一点关于Python中的内存管理和优化。在打好基础之后,我解释了赋值语句、浅拷贝和深拷贝之间的区别。然后我用一个表格总结了这些区别。

Python中的内存管理

int, float, list, dict, class instances, ...它们都是Python中的对象。在CPython的实现中,内置函数id()返回一个对象的内存地址--

>>> L1 = [1, 2, 3]>> id(L1)3061530120
>>> L2 = [1, 2, 3]>>> id(L2)3061527304每当一个新的对象被创建,它将有一个新的内存地址。除了当它是--一个非常短的字符串一个在[-5, 256]内的整数一个空的不可变的容器(例如 元组)。让我们看一个整数对象的例子。x和y都指的是同一个值10。在前面的例子中,L1和L2有两个不同的内存地址,而x和y则共享同一个内存地址-->>> x = 10>>> y = 10>>> id(x)2301840>>> id(y)2301840这是因为,在这三个例外中,Python 通过让第二个变量引用内存中的同一个对象来优化内存,--有人称之为 "共享对象"。请记住共享对象的概念,因为我们以后在创建一个对象的深拷贝时将需要它。变量赋值在 Python 文档中说:"Python 中的赋值语句不是复制对象,而是在目标和对象之间建立绑定。" 这意味着当我们通过赋值创建一个变量时,新的变量指的是与原始变量相同的对象----。>>> A = [1, 2, [10, 11], 3, [20, 21]]>> B = A>>> id(A)3061527080>>> id(B)3061527080
>>> id(A[2])3061527368>>> id(B[2])3061527368
如下图所示,A和B共享相同的id,即它们在内存中引用的是同一个对象。而且它们也包含相同的元素。
浅层拷贝当我们通过浅层拷贝创建一个变量时,新的变量会指向一个新的对象--
>>> A = [1, 2, [10, 11], 3, [20, 21]]>> C = copy(A)>>> id(A)3062428488
>> id(C)3062428520
>>> id(A[0])2301696
>>> id(C[0])2301696
>>> id(A[2])3062464904
>>> id(C[2])3062464904
下图说明了A中的元素如何与C中的元素指代相同的对象。深度复制>>> A = [1, 2, [10, 11], 3, [20, 21]]>> D = deepcopy(A)>>> id(A)3062727496>> id(D)3062428488正如Python文档中描述的那样--浅拷贝和深拷贝的区别只与复合对象 (包含其他对象的对象,如列表或类实例) 有关。- 浅拷贝构造一个新的复合对象,然后 (尽可能地) 在其中插入对原始对象的引用。- 深度拷贝构造一个新的复合对象,然后递归地将原始对象的副本插入其中。>>> id(A[0])2301696
>>> id(D[0])2301696
>>> id(A[2])3062464648
>>> id(D[2])3062466376但是为什么A[0]和D[0]共享同一个对象(即有相同的内存地址)?因为它们都引用了整数,这是我们在开始时提到的由于内存优化而出现的三种例外情况之一。下图显示A和D指的是内存中两个不同的列表,A中的元素与D中的元素指的是不同的对象,除了由于内存优化的整数元素。

标签:对象,list,内存,拷贝,copy,id
From: https://www.cnblogs.com/Raul2018/p/17643755.html

相关文章

  • DTO、对象拷贝——多表查、修改、添加
    问题介绍一:一个分页查询方法,前端页面需要展示菜品信息(dish表),和菜品类型id信息(categoryId),但是菜品类型类中的菜品分类属性字段,菜品表中没有,所以使用DTO类,将两类信息保存到一个DTO类中。1、DishDto类其中该类继承Dish,所以有Dish类中的所有字段属性,本身自带categoryName属性与List......
  • 浅拷贝和深拷贝
    前言面试的时候经常会问到深拷贝和浅拷贝,那么python的深拷贝和浅拷贝有什么区别呢?思考题先来看2个简单的案例,对元素a/aa重新赋值一个新的变量b/bb后,改变原来a/aa的值,看会不会影响新的变量b/bb的值#1.stra="hello"b=aa="world"print('a:{}'.format(a))......
  • winform编译时怎么把指定dll拷贝到debug里面(非引用)
    选中winform项目-》右键属性-》选择生成事件-》在生成后事件命令行配置以下代码Copy"$(ProjectDir)dll\*.*""$(ProjectDir)$(OutDir)" ......
  • 8.1 C++ STL 变易拷贝算法
    C++STL中的变易算法(ModifyingAlgorithms)是指那些能够修改容器内容的算法,主要用于修改容器中的数据,例如插入、删除、替换等操作。这些算法同样定义在头文件<algorithm>中,它们允许在容器之间进行元素的复制、拷贝、移动等操作,从而可以方便地对容器进行修改和重组。主要包括以下......
  • 8.1 C++ STL 变易拷贝算法
    C++STL中的变易算法(ModifyingAlgorithms)是指那些能够修改容器内容的算法,主要用于修改容器中的数据,例如插入、删除、替换等操作。这些算法同样定义在头文件<algorithm>中,它们允许在容器之间进行元素的复制、拷贝、移动等操作,从而可以方便地对容器进行修改和重组。主要包括以下......
  • 对象拷贝方法
    C#中4种深拷贝方法介绍概述为什么要用到深拷贝呢?比如我们建了某个类Person,并且实例化出一个对象,然后,突然需要把这个对象复制一遍,并且复制出来的对象要跟之前的一模一样,来看下我们一般会怎么做。1、利用反射实现publicstaticTDeepCopy(Tobj){//如果是字符串或值类型则......
  • Python 对象拷贝的详细教程
    在本篇文章中,会先介绍Python中对象的基础概念,之后会提到对象的深浅拷贝以及区别。在阅读后,应该掌握如下的内容:理解变量、引用和对象的关系理解Python对象中identity,type和value的概念什么是mutable和immutable对象?以及它们和hashable的关系深浅拷贝的过程以及区别1.......
  • 解读 --- 对象的深拷贝
    合集-c#基础(12) 1.编码技巧---如何实现字符串运算表达式的计算07-122.编码技巧---同步锁对象的选定07-133.编码技巧---使用dynamic简化反射07-244.编码技巧---谨防闭包陷阱07-195.并发编程---信号量线程同步07-186.并发编程---为何要线程池化07-187.并发编程......
  • 解读 --- 深拷贝
    引言深拷贝是指创建一个新对象,该对象的值与原始对象完全相同,但在内存中具有不同的地址。这意味着如果您对原始对象进行更改,则不会影响到复制的对象常见的C#常见的深拷贝方式有以下4类:各种形式的序列化及反序列化。通过反射机制获取该对象的所有字段和属性信息。遍历所有字段......
  • Python 对象拷贝的详细教程
    在本篇文章中,会先介绍Python中对象的基础概念,之后会提到对象的深浅拷贝以及区别。在阅读后,应该掌握如下的内容:理解变量、引用和对象的关系理解Python对象中identity,type和value的概念什么是mutable和immutable对象?以及它们和hashable的关系深浅拷贝的......