python深拷贝和浅拷贝详解_Java浅拷贝和深拷贝的区别

python深拷贝和浅拷贝详解_Java浅拷贝和深拷贝的区别Python深拷贝和浅拷贝详解浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。1.浅拷贝使用数据类型本身的构造器对于可变的序列,还可以通过切片操作符:来完成浅拷贝Python还提供了对应的函数copy.copy()函数,适用于任何数据类型1.1使用数据类型本身的构造器lis

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

1、Python 深拷贝和浅拷贝概念理解

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

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

2、浅拷贝

  • 使用数据类型本身的构造器
  • 对于可变的序列,还可以通过切片操作符 : 来完成浅拷贝
  • Python 还提供了对应的函数 copy.copy() 函数,适用于任何数据类型

2.1 使用数据类型本身的构造器

list1 = [1, 2, 3]
list2 = list(list1)
print(list2)
print("list1==list2 ?",list1==list2)
print("list1 is list2 ?",list1 is list2)

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)

[1, 2, 3]
list1==list2 ? True
list1 is list2 ? False

{ 
   1, 2, 3}
set1==set2 ? True
set1 is set2 ? False

{ 
   1: [1, 'w'], 2: 0, 3: 98}
dict1 == dict2 ? True
dict1 is dict2 ? False

Jetbrains全家桶1年46,售后保障稳定

分析: 浅拷贝,为新变量重新分配一块内存,和原来变量的内存不一样,所以有

list1 is list2 ? False
set1 is set2 ? False
dict1 is dict2 ? False

但浅拷贝完,两个变量中的元素的值是一样的。

list1==list2 ? True
dict1 == dict2 ? True
set1==set2 ? True

2.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

2.3 使用 copy.copy() 函数

函数 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)

[1, 2, 3]
list1 == list2 ? True
list1 is list2 ? False

{ 
   1, 2, 3}
set1 == set2 ? True
set1 is set2 ? False

{ 
   1: 'xiaoming', 2: 'xiahua', 3: 'xiaoli'}
dict1 == dict2 ? True
dict1 is dict2 ? False

2.4 对于元组

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

tuple1 = (1, 2, 3)
tuple2 = tuple(tuple1)
print(tuple2)
print("tuple1 == tuple2 ?",tuple1 == tuple2)
print("tuple1 is tuple2 ?",tuple1 is tuple2)

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

(1, 2, 3)
tuple1 == tuple2 ? True
tuple1 is tuple2 ? True

(1, 2, 3)
tuple1 == tuple2 ? True
tuple1 is tuple2 ? True

使用 tuple() 或者切片操作符 ‘:’ 不会创建一份浅拷贝,因为它开辟新的内存存储的是原对象的引用,而没有创建新的对象来存储原对象的子对象的引用,所以不是浅拷贝。相反它会返回一个指向相同元组的引用。

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

str1 = 'operation'
str2 = str1[:]
print(str2)
print("str1 == str2 ?",str1 == str2)
print("str1 is str2 ?",str1 is str2)

operation
str1 == str2 ? True
str1 is str2 ? True
str1 = 'operation'
str2 = str(str1)
print(str2)
print("str1 == str2 ?",str1 == str2)
print("str1 is str2 ?",str1 is str2)

operation
str1 == str2 ? True
str1 is str2 ? True
import copy

set1 = (1, 2, 3)
set2 = copy.copy(set1)
print(set2)
print("set1 == set2 ?",set1 == set2)
print("set1 is set2 ?",set1 is set2)

(1, 2, 3)
set1 == set2 ? True
set1 is set2 ? True
import copy

set1 = 'operation'
set2 = copy.copy(set1)
print(set2)
print("set1 == set2 ?",set1 == set2)
print("set1 is set2 ?",set1 is set2)

operation
set1 == set2 ? True
set1 is set2 ? True

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

2.5 关于切片操作符 ‘:’

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

# set1 = {1, 2, 3}
# set2 = set1[:]

# dict1 = {1:1, 2:2, 3:3}
# dict2 = dict1[:]

2.6 和赋值的区别

和赋值的本质区别在于,赋值只是把原对象的引用给到新对象

set1 = { 
   1:1, 2:2, 3:3}
set2 = set1
print(set2)
print("set1 == set2 ?",set1 == set2)
print(id(set1))
print(id(set2))

{ 
   1: 1, 2: 2, 3: 3}
set1 == set2 ? True
2515252654368
2515252654368

2.7 浅拷贝需注意的问题

对数据采用浅拷贝的方式时,如果原对象中的元素不可变,那倒无所谓;但如果元素可变,浅拷贝通常会出现一些问题,

list1 = [[1, 2], (30, 40)]
list2 = list(list1)
list1.append(100)
print("list1:",list1)
print("list2:",list2)
list1[0].append(3)
print("list1:",list1)
print("list2:",list2)
list1[1] += (50, 60)
print("list1:",list1)
print("list2:",list2)

list1: [[1, 2], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40), 100]
list2: [[1, 2, 3], (30, 40)]
list1: [[1, 2, 3], (30, 40, 50, 60), 100]
list2: [[1, 2, 3], (30, 40)]

2、深拷贝

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

import copy

list1 = [[1, 2], (30, 40)]
list2 = copy.deepcopy(list1)

list1.append(100)
print("list1:",list1)
print("list2:",list2)

list1[0].append(3)
print("list1:",list1)
print("list2:",list2)

list1[1] += (50, 60)
print("list1:",list1)
print("list2:",list2)

list1: [[1, 2], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40, 50, 60), 100]
list2: [[1, 2], (30, 40)]
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203548.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机组成原理 寻址方式_计算机组成原理寻址方式的判断

    计算机组成原理 寻址方式_计算机组成原理寻址方式的判断一、寻址方式是指确定本条指令的数据地址以及下一条将要执行的指令地址的方法,与硬件结构紧密相关,而且直接影响指令格式和指令功能。分为指令寻址和数据寻址两大类。二、指令寻址分为顺序寻址和跳跃寻址两种。顺序寻址可通过程序计数器PC加1,自动形成下一条指令的地址;跳跃寻址则通过转移类指令实现。数据寻址种类较多,在指令字中必须设一字段来指明属于哪一种寻址方式。指令的地址码字段通常都不代表操作数的真实地址,把它称为真实地址,记作A。操作数的真实地址成为有效地址,记作EA,它是由寻址方式和形式地址共同来确定的。由

    2022年10月24日
    0
  • win764位旗舰版的序列号(个人推荐可以使用可靠的激活成功教程工具)

    win764位旗舰版的序列号(个人推荐可以使用可靠的激活成功教程工具)87VT2-FY2XW-F7K39-W3T8R-XMFGF2VCGQ-BRVJ4-2HGJ2-K36X9-J66JGMGX79-TPQB9-KQ248-KXR2V-DHRTDFJHWT-KDGHY-K2384-93CT7-323RC企业版专业版密钥:W2F97-F3C67-JFHYH-YK7TW-FCGXW密钥:MBR2C-Q3HDQ-46VG2-WVBYQ-Y…

    2022年7月20日
    14
  • win系统JDK卸载和彻底删除

    win系统JDK卸载和彻底删除▌第一步:进入“控制面板”。▌第二步:进入“卸载程序”。▌第三步:进入到“程序和功能”界面找到jdk的两个程序:①java8update171(64-bit);②javaSEDevelopmentKit8update171(64-bit);分别右键卸载▌第四步:删除注册表编辑器中的文件在“运行”中输入Regedit,进入注册表编辑器,找到HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft,将JavaSoft文件夹及其子目录全部删除…

    2022年6月24日
    75
  • win10黑群晖安装教程_黑群晖7.0安装教程

    win10黑群晖安装教程_黑群晖7.0安装教程使用芯片无忧工具,查看U盘的和。使用,格式化U盘。使用镜像写入工具,把引导写入U盘。修改文件,可以使用工具把文件复制到桌面,通过修改好之后,拖进这个界面中。或者在电脑中,查看U盘,打开U盘中的文件直接修改。具体修改内容如下:,因为我的主板上有4个sata口,然后PCIE扩展了6个SATA口,所以这里写了46,分别对应主板的SATA数目和PCIE的SATA数目。,因为主板的4个SATA口分别为00、01、02、03,所以PCIE的SATA从04开始。也就是说,前面两个00代表主板上的SATA控制从00开始计数

    2025年6月14日
    1
  • webstrom的格式化代码快捷键

    webstrom的格式化代码快捷键windows下webstorm格式化代码的快键键Ctrl+Alt+lmac下webstorm格式化代码的快捷键Option+Command+lcentOS下webstorm格式化代码的快捷键Ctrl+Shift+l windows下webstorm格式化代码的快键键Ctrl+Alt+lmac下webstorm格式化代码的快捷键Option+Command+l…

    2022年5月2日
    39
  • ug与solidworks比较_如何比较

    ug与solidworks比较_如何比较ug是个综合性很强大,sw机械设计方面很强大。工业设计用solidworks较好,模具设计用UG为好。UG适合大型产品,如飞机,汽车,轮船,solidworks适合小型机械产品。UG是想做什么

    2022年8月6日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号