首页 > 编程语言 >Python 深拷贝和浅拷贝详解

Python 深拷贝和浅拷贝详解

时间:2023-12-07 23:33:58浏览次数:33  
标签:Python list1 list2 tuple1 tuple2 详解 print 拷贝

import logging  

一、深拷贝和浅拷贝概念理解

1、浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。

2、深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

3、对于不可变对象,深拷贝和浅拷贝的效果是一样的,因为不可变对象不需要在内存中复制

4、对于可变对象,深拷贝和浅拷贝的效果是有区别的,主要原因在于可变对象自身的可变性质

二、浅拷贝

浅拷贝,为新变量重新分配一块内存,和原来变量的内存不一样,但浅拷贝完,两个变量中的元素的值是一样的。

切片操作符 ‘:’ 不能用于字典和集合完成浅拷贝

浅拷贝是创建一个新对象,该对象的内容是原始对象的引用。换句话说,新对象与原始对象共享内存中的某些部分。当对其中一个对象进行更改时,另一个对象也会受到影响。浅拷贝可以通过切片操作符([:])或使用copy模块中的copy()函数来实现。

1、使用数据类型本身的构造器(list() dict() set() 等)

list1 = [1, 2, 3]
list2 = list(list1)
print(list2)
print("list1==list2 ?",list1==list2) # list1==list2 ? True
print("list1 is list2 ?",list1 is list2) # list1 is list2 ? False
 
set1= set([1, 2, 3])
set2 = set(set1)
print(set2)
print("set1==set2 ?",set1==set2)
print("set1 is set2 ?",set1 is set2)
 
dict1 = {1:[1,'w'], 2:0, 3:98}
dict2 = dict(dict1)
print(dict2)
print("dict1 == dict2 ?",dict1 == dict2)
print("dict1 is dict2 ?",dict1 is dict2)

 

2、对于可变的序列,还可以通过切片操作符 : 来完成浅拷贝

list1 = [1, 2, 3]
list2 = list1[:]
print(list2)
print("list1 == list2 ?",list1 == list2)
print("list1 is list2 ?",list1 is list2)
 
[1, 2, 3]
list1 == list2 ? True
list1 is list2 ? False

 

3、Python 还提供了对应的函数 copy.copy() 函数,适用于任何数据类型

import copy
 
list1 = [1, 2, 3]
list2 = copy.copy(list1)
print(list2)
print("list1 == list2 ?",list1 == list2)
print("list1 is list2 ?",list1 is list2)
 
set1 = {1, 2, 3}
set2 = copy.copy(set1)
print(set2)
print("set1 == set2 ?",set1 == set2)
print("set1 is set2 ?",set1 is set2)
 
dict1 = {1:'xiaoming', 2:'xiahua',3:'xiaoli'}
dict2 = dict(dict1)
print(dict2)
print("dict1 == dict2 ?",dict1 == dict2)
print("dict1 is dict2 ?",dict1 is dict2)

 

4、对于元组,使用 tuple() 或者切片操作符 ‘:’ 不会创建一份浅拷贝,相反它会返回一个指向相同元组的引用

tuple1 = (1, 2, 3)
tuple2 = tuple(tuple1)
print(tuple2)  # (1, 2, 3)
print("tuple1 == tuple2 ?",tuple1 == tuple2) # tuple1 == tuple2 ? True
print("tuple1 is tuple2 ?",tuple1 is tuple2) # tuple1 is tuple2 ? True
 
tuple1 = (1, 2, 3)
tuple2 = tuple1[:]
print(tuple2) # (1, 2, 3)
print("tuple1 == tuple2 ?",tuple1 == tuple2) # tuple1 == tuple2 ? True
print("tuple1 is tuple2 ?",tuple1 is tuple2) # tuple1 is tuple2 ? True

 

对字符串使用 str() 或者切片操作符 ‘:’,原理和 元组相同。

也就是说,对字符串和元组使用 copy()、[:]、本身的构造器完成的复制,都只是开辟了内存存储原对象的引用,而不是存储原对象的子对象的引用。

三、深拷贝

Python 中以 copy.deepcopy() 来实现对象的深度拷贝

深拷贝会创建一个新对象,并且递归地复制原始对象及其内容,而不仅仅是引用。深拷贝不共享任何内存地址,因此对其中一个对象的更改不会影响另一个对象。

import copy
 
list1 = [[1, 2], (30, 40)]
list2 = copy.deepcopy(list1)  # 深拷贝
list3 = copy.copy(list1)     # 浅拷贝
 
list1[0].append(100)   # 子元素添加值
print("list1:", list1)  # list1 变
print("list2:", list2)  # 深拷贝以后和list1没有关系,list2不变
print("list3:", list3)  # 浅拷贝是存储原对象的子对象的引用,所以跟着改变

标签:Python,list1,list2,tuple1,tuple2,详解,print,拷贝
From: https://www.cnblogs.com/Jessica-Jmm/p/17884252.html

相关文章

  • 聪明办法学python-12.4——12.8笔记打卡
     python中Debug的方法  必要性:在于程序可能出现不符合预期结果的情况 困难:在于bug的出触发原因多种多样,只能看到最终结果 调试代码的基本思路:让bug在设计时更容易暴露出来,包括利用print和断言来解决简单问题,利用IDE进行调试 常见的错误:函数未定义会报错,需要检查函数......
  • Python的hashlib模块
    一、什么是摘要算法1、摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)用于生成数据或文本的简短摘要或哈希值的算法。它们被广泛应用于密码学、数据完整性验证和信息检索等领域。摘要算法通过对输入数据进......
  • debug-聪明办法学Python
    如何Debug调试理论开始调试之前通过不断地调试,比如在循环中打印某个元素检查不得不承认机器永远只认编程语言不过你必须要时刻关注你的变量名称是否发生变更,这在大改前必须要注意的调试已知程序有bug,如何找到?调试困难的根本原因因为bug的触发经历了漫长的过程需求->设......
  • Python之的sys、os、subprocess、shutil 模块
    一、sys模块 sys模块是与python解释器交互的一个接口1、sys.argv() 在Python中,sys.argv是一个列表,它包含了命令行参数传递给Python脚本的参数值。sys.argv列表的第一个元素是脚本的名称,后面的元素是传递给脚本的参数。importsys#打印脚本名称print("脚本名称:",s......
  • python第五次学习笔记
    1.调试: 调试(debugging)是暂停正在运行的程序,并解决程序中出现的问题的过程。调试Python程序非常简单,Python调试器会设置条件断点,并一次执行一行代码。接下来我们将使用Python标准库中的pdb模块调试Python程序。2.调试技术: 我们可以使用多种方法调试Python程序,以下是调试......
  • Python的json序列化模块
    一、jsonJson模块提供了四个功能:dumps、dump、loads、load1、前景什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。序列化的目的以某种存储形式使自定义对象持久化;将对象从一个地方传递到另一个地方。使程序更具维护性在Python中,能够......
  • 详解网络数据包接受的过程
    在tcp_v4_rcv中,得到TCP的头之后,我们可以开始处理TCP层的事情。因为TCP层是分状态的,状态被维护在数据结构structsock里面,因而我们要根据IP地址以及TCP头里面的内容,在tcp_hashinfo中找到这个包对应的structsock,从而得到这个包对应的连接的状态。接下来,我们就根据......
  • Thread常见方法:join 方法详解
    为什么需要join下面的代码执行,打印r是什么?staticintr=0;publicstaticvoidmain(String[]args)throwsInterruptedException{test1();}privatestaticvoidtest1()throwsInterruptedException{log.debug("开始");Threadt1=newThread(()->{log.de......
  • python的异步迭代器含义
    python的异步迭代器什么意思?什么是迭代器:迭代器是一种遵循迭代器协议的对象,可以被用在像for循环这样的迭代环境中。迭代器协议包含两个方法:__iter__():返回迭代器自身。__next__():返回迭代器的下一个元素。如果没有更多元素,则抛出StopIteration异常。就是这两个方法要包......
  • python-文件IO操作实例
    一、如何复制文件1、使用shutil模块来复制importshutil#导入shutil模块#定义源文件和目的文件的路径#图片src_path="E:/python/py/基础篇/01_基础/06_文件操作/图片.jpg"dst_path="D:/图片.jpg"#文本src1_path="E:/python/py/基础篇/01_基础/06_文件操作/......