c++ list容器获取第n给元素_容器对象与浅拷贝深拷贝的关系

3.对象的分类:

容器对象:[1]

容器对象中包含的元素,是指向各个元素对象的引用。 (并不是元素对象本身。)

list、dict、set、tuple、str

1ac9c51675adc62e6d8732fb6b7b6587.png

序列对象:[2]

是有序集合,可以使用索引、切片功能。list、str、tuple

14524bf3ce42b79bf771408cdc103ea4.png

28fafa813f2278688b8586c58d61f365.png

90694272516487729673be3589eb1610.png

cac64bc8792dc49ba1620e9a2ed1057a.png

在Python中,

对象赋值实际上是对象的引用。[3]

创建一个对象,把它赋给另一个变量的时候,只拷贝这个对象的引用。(没拷贝这个对象)

1、浅拷贝:利用切片操作、工厂方法list方法拷贝

2、深拷贝:利用copy中的deepcopy方法进行拷贝

赋值引用'=':就是给将对象的引用赋值给变量,即给一段内存地址贴标签

对于不可变对象,=、copy、deepcopy三者等价。[4]

针对可变对象 list,[:] 复制列表中的所有元素(浅拷贝)。

eek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[:])  
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

list [:] 的浅拷贝 [5]

m = [1, 2, 3]
print('m', m, id(m))

n = m[:]
print('n', n, id(n))

n[1] = 4
print('m', m)
print('n', n)

2、浅拷贝 shallow copy[6]

拷贝父对象的副本,但不会拷贝对象的内部的子对象

构造一个新的对象并将原对象中的引用插入到新对象中,只拷贝了对象的地址,而不对对应地址所指向的具体内容进行拷贝,也就是依然使用原对象的引用。

浅拷贝只是拷贝了原始元素的引用(内存地址),拷贝对象的值是否会随着被拷贝对象变化,仅取决于原始元素是可变对象还是不可变对象。

[7]

90694272516487729673be3589eb1610.png

3、深拷贝

完全拷贝了父对象及其子对象

深拷贝复制的不只是原始元素的引用,而是整个原始元素对象。

因此,拷贝对象和被拷贝对象的值相互独立。

cac64bc8792dc49ba1620e9a2ed1057a.png

浅拷贝与深拷贝

list1 = [123, 456, 789, 213]
list2 = list1
list3 = list1[:]

print(list2)  # [123, 456, 789, 213]
print(list3)  # [123, 456, 789, 213]
list1.sort()
print(list2)  # [123, 213, 456, 789] 
print(list3)  # [123, 456, 789, 213]

list1 = [[123, 456], [789, 213]]
list2 = list1
list3 = list1[:]
print(list2)  # [[123, 456], [789, 213]]
print(list3)  # [[123, 456], [789, 213]]
list1[0][0] = 111
print(list2)  # [[111, 456], [789, 213]]
print(list3)  # [[111, 456], [789, 213]]

一.浅拷贝

a 和 b 是一个独立的对象,他们的子对象还是引用同一对象[8]

浅拷贝后,若改变可变对象元素的值,会同时影响浅拷贝对象;若改变不可变对象元素的值,不会响浅拷贝对象。

实现方式包括:工厂函数:list(), set()等、切片,copy模块的copy()方法。

#定义一个列表,第一个元素是可变类型
>>> A = [[1,2],'fei',90]

#浅拷贝
>>> B = copy.copy(A)

#对象地址是否相同
>>> A is B
False

#第一个元素地址是否相同
>>> A[0] is B[0]
True

#第二个元素地址是否相同
>>> A[1] is B[1]
True

#改变第一个可变类型的值,查看复制对象变化
>>> A[0][0] = 2
>>> A
[[2, 2], 'fei', 90]

#复制对象也跟着改变了
>>> B
[[2, 2], 'fei', 90]

#改变第二个不可变类型的值,查看复制对象变化
>>> A[1] = 'anne'
>>> A
[[2, 2], 'anne', 90]

#复制对象没有改变
>>> B
[[2, 2], 'fei', 90]

二.深拷贝

完全拷贝了父对象及其子对象[9],深拷贝得到的对象和原对象是完全独立的。

深拷贝,除了顶层拷贝,还对自对象也进行了拷贝。

经过深拷贝后,原始对象和拷贝对象所有的可变对象元素的地址都不相同。

实现方式:copy 模块的 deepcopy() 方法。

#深拷贝
>>> C = copy.deepcopy(A)

#对象地址是否相同
>>> A is C
False

#第一个元素地址是否相同
>>> A[0] is C[0]
False

#第二个元素地址是否相同
>>> A[1] is C[1]
True

#改变第一个元素,查看复制元素变化
>>> A[0][0] = 2
>>> A
[[2, 2], 'fei', 90]

#复制元素不变,对复制元素没影响
>>> C
[[1, 2], 'fei', 90]

#改变第二个元素,查看复制元素变化
>>> A[1] = 'Anne' >>> A
[[2, 2], 'Anne', 90]

#复制元素不变,对复制元素没影响
>>> C
[[1, 2], 'fei', 90]

三.赋值引用

a 和 b 都指向同一个对象。

#赋值引用
>>> A = [[1,2],'fei',90]
>>> D = A

#对象地址是否相同
>>> A is D
True

#第一个元素地址是否相同
>>> A[0] is D[0]
True

#第二个元素地址是否相同
>>> A[1] is D[1]
True

#改变A中第一个元素,查看是否影响D
>>> A[0][0] = 2
>>> A
[[2, 2], 'fei', 90]

#D中第一个元素也跟着改变
>>> D
[[2, 2], 'fei', 90]

#改变D中第二个元素,查看是否影响A
>>> D[1] = 'anne'

#A中第二个元素也改变了
>>> A
[[2, 2], 'anne', 90]
>>> D
[[2, 2], 'anne', 90]

[10]

fce25d6f9a01aa9295c7e37f5ff29c10.png

参考

  1. ^容器对象 https://www.cnblogs.com/geaozhang/p/7111961.html
  2. ^序列对象和拆包 https://blog.csdn.net/weixin_44435602/article/details/110234494
  3. ^赋值引用、浅拷贝、深拷贝 https://www.cnblogs.com/geaozhang/p/7116025.html
  4. ^不可变对象,赋值、浅拷贝、深拷贝,三者等价: https://zhuanlan.zhihu.com/p/115242988
  5. ^切片、浅拷贝、深拷贝的区别: https://zhuanlan.zhihu.com/p/39566815
  6. ^浅拷贝、深拷贝: https://www.cnblogs.com/ybjourney/p/12951678.html
  7. ^浅拷贝、深拷贝 https://zhuanlan.zhihu.com/p/40449219
  8. ^浅拷贝与深拷贝(图) https://www.cnblogs.com/jiangfan95/p/11466398.html
  9. ^深拷贝 https://zhuanlan.zhihu.com/p/115242988
  10. ^图 https://www.cnblogs.com/jiangfan95/p/11466398.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值