首页 > 其他分享 >赋值,浅拷贝,深拷贝

赋值,浅拷贝,深拷贝

时间:2023-04-01 22:01:11浏览次数:36  
标签:对象 元素 list1 列表 拷贝 list2 赋值

在 Python 中,浅拷贝、深拷贝和赋值,它们之间的区别在于它们复制对象的方式,具体可以分别如下:

1.赋值(相当于对象引用)

赋值只是将一个变量指向一个已存在的对象,这个变量与这个对象就共享了一个内存地址,当修改这个对象时,所有指向它的变量都会发生变化,例如:

list1 = [1, 2, 3]
list2 = list1  # list2 是 list1 的引用

现在 list2 是 list1 的引用,它们的内存地址相同,所以如果修改 list1, list2 也会相应发生变化:

list1.append(4)
print(list2)  # 输出 [1, 2, 3, 4]

2.浅拷贝

浅拷贝会复制原对象的引用,进而创建一个新的对象,但是这个新的对象中的可变元素与原对象中的元素还是会共享内存地址,对于不可变元素则是复制值,例如:

list1 = [1, 2, [3, 4]]
list2 = list1.copy()  # 进行浅拷贝

虽然 list1 和 list2 现在是两个不同的对象了,但是它们中嵌套的列表还保持着相同的内存地址,意味着如果修改嵌套在列表里面的元素,这两个列表都会改变:

list1[2].append(5)
print(list1)  # 输出 [1, 2, [3, 4, 5]]
print(list2)  # 输出 [1, 2, [3, 4, 5]]

对于不可变对象的浅拷贝

不可变对象指的是如 int、float、str、tuple 等类型的对象,它们的值不能被修改。在浅拷贝不可变对象时,会创建一个新的对象,并将原对象中的元素复制到新的对象中。因为不可变对象是不可变的,所以无论是新的对象还是原来的对象,都无法修改其元素值。因此,浅拷贝会产生一个与原对象独立的新对象。

下面是一个对不可变对象进行浅拷贝的例子:

# 对整数进行浅拷贝
a = 1
b = a.copy()  # 会抛出 AttributeError

这段代码会抛出一个 AttributeError 异常,因为整数对象是不可变类型,不支持 copy() 方法。

对于可变对象的浅拷贝

可变对象指的是如 list、dict、set 等类型的对象,它们的值可以被修改。在浅拷贝可变对象时,会创建一个新的对象(浅拷贝只会拷贝对象的第一层数据),并将原对象中的元素的引用复制到新的对象中。因为新对象中的可变元素只是原对象中可变元素的引用,所以新对象中的元素与原对象中的元素会共享一段内存空间。因此,当修改新对象或原对象的可变元素时,两个对象都会受到影响。

下面是一个对可变对象进行浅拷贝的例子:

# 对列表进行浅拷贝
a = [1, [2, 3]]
b = a.copy()

# 修改 b 列表中第二个元素的值
b[1][0] = 4

print(a)  # [1, [4, 3]]
print(b)  # [1, [4, 3]]

这段代码创建了一个列表对象 a,并将其赋值给变量 b。然后修改 b 列表中第二个元素的值,这也会修改 a 列表中的第二个元素的值。因为 a 和 b 是两个对象,但是它们中的第二个元素都指向了同一个列表对象 [2, 3],所以修改了 b 中的值也会修改 a 中的值。

需要注意的是,浅拷贝只会拷贝对象的第一层,对于嵌套的可变对象,浅拷贝只会拷贝它们的引用,而不会创建新的对象。下面是一个嵌套的列表进行浅拷贝的例子:

# 对嵌套的列表进行浅拷贝
a = [[1, 2], [3, 4]]
b = a.copy()

# 修改 b 列表中第一个元素的值
b[0][0] = 5

print(a)  # [[5, 2], [3, 4]]
print(b)  # [[5, 2], [3, 4]]

这段代码创建了一个嵌套的列表对象 a,并将其赋值给变量 b。然后修改 b 列表中第一个元素的值,这也会修改 a 列表中的第一个元素的值。因为 a 和 b 是两个对象,但是它们中的第一个元素都指向了同一个列表对象 [1, 2],所以修改了 b 中的值也会修改 a 中的值。

总之,对于可变对象的浅拷贝,需要注意其嵌套层数,浅拷贝只会拷贝对象的第一层,如果对象中还嵌套着可变对象,那么这些可变对象只会被拷贝一次,而不会被重新创建。

3.深拷贝

深拷贝会递归地复制嵌套在原始对象中的所有对象,不论这些对象是否可变,这样能够生成一个不同的、完全独立的新对象。例如:

import copy

list1 = [1, 2, [3, 4]]
list2 = copy.deepcopy(list1)  # 进行深拷贝

现在,list1 和 list2 是完全独立的新对象,中嵌套列表的元素也是独立的:

list1[2].append(5)
print(list1)  # 输出 [1, 2, [3, 4, 5]]
print(list2)  # 输出 [1, 2, [3, 4]]

这里修改了 list1 中嵌套列表的值,但是 list2 并没有受到影响,因为它们是完全独立的,共享的内存地址是不同的。

标签:对象,元素,list1,列表,拷贝,list2,赋值
From: https://www.cnblogs.com/zouzhibin/p/17279497.html

相关文章

  • 运算符【算术运算符/赋值运算符/比较运算符/逻辑运算符】
     算术运算符   赋值运算符:  比较运算符  逻辑运算符:  运算符优先级:  其他运算符查看官方教程 来源:https://www.runoob.com/python/python-operators.html......
  • java两个不同类的对象相同属性赋值
    一、外部工具包Java中有很多工具包可以用来实现对象属性复制,其中比较常用的有以下几个:ApacheCommonsBeanUtils:提供了一组简单易用的API,可以实现对象属性的复制、获取、设置等操作。SpringFrameworkBeanUtils:与ApacheCommonsBeanUtils类似,提供了一组API,可以实现对......
  • 小程序 page 和 onLoad 的赋值
    貌似page中的赋值只会执行一次,而不是进入此页面后执行一次,例如:data:{title:'您认为别人是这样的吗?',bubblesTextList:app.globalData.mood_1},onLoad(options){},那么获取到的bubblesTextList永远不会改变,及时你在下面对globalData重新赋值,解......
  • C++编程语言中赋值运算符重载函数(operator=)介绍
    参考资料:C++编程语言中赋值运算符重载函数(operator=)介绍_operator==_liitdar的博客-CSDN博客本文主要介绍C++编程语言中赋值运算符重载函数(operator=)的相关知识,同时通......
  • 使用memset对数组进行赋值时可能会有的疑惑
    Memset(typename,intvalue,size) *第一个参数为变量的标识符,第二个要赋为数组的值,第三个为数组的大小(单位为字节,可用sizeof()表示)原理:memset是字节为单位进行复制......
  • [软件体系结构/架构]零拷贝技术(Zero-copy)[转发]
    0前言近期遇到难题:1个大数据集的查询导出API,因从数据库查询后占用内存极大,每次调用将消耗近100MB的JVM内存资源。故现需考虑研究和应用零拷贝技术。如下全文摘自:看一......
  • 拷贝
    C++中拷贝使用的时机:1.使用一个创建完毕的对象来初始化一个新的对象。Peoplep1;Peoplep2(p1);     //使用了拷贝,赋值了各个值......
  • es6中2个对象之间传值赋值
    在ES6中,可以使用对象解构赋值语法将一个对象的属性值赋给另一个对象。例如:constobj1={foo:1,bar:2};constobj2={baz:3};//将obj1的属性foo和bar赋值给......
  • 深拷贝函数
    //使用map生成考虑了所有情况的深拷贝函数functiondeepClone(obj,map=newWeakMap()){//基本类型直接返回if(typeofobj!=="object"||obj===null){......
  • poi 导入excel (懒人拷贝代码用)(jdbctemplate)oms版本
     相关内容:1,jdbcTemplate批量导入2,js原始产生form动态产生文件选择框3,反射机制调用set方法 <divclass="l-bar-separator"></div><divclass="group"><aclass="linkad......