python中list的深拷贝和浅拷贝

其实这还是涉及到python中的可变对象和不可变对象的概念。

https://www.cnblogs.com/poloyy/p/15073168.html

对于多维list来说,浅拷贝就是考的第一层的地址。

list拷贝的时候发生了什么:

# -*- coding: utf-8 -*-

person = ['name', ['savings', 100.00]]
hubby = person[:] # slice copy
wifey = list(person) # fac func copy
a = [id(x) for x in person]
b = [id(x) for x in hubby]
c = [id(x) for x in wifey]
print("person", a) # person [2581907861552, 2582842106496]
print("hubby", b) # hubby [2581907861552, 2582842106496]
print("wifey", c) # wifey [2581907861552, 2582842106496]

print(id(a), id(b), id(c)) # 2582843034240 2582843034496 2582843035200

hubby[0] = "Jack" 
# ------------------------!!!!!------------------
# 第一步: 等号右边,创建"Jack"字符串,第二步:将"Jack"的地址链接到hubby的第一个元素上
# ------------------------!!!!!------------------
print(person, hubby, wifey)
# ['name', ['savings', 100.0]] ['Jack', ['savings', 100.0]] ['name', ['savings', 100.0]]
print(id(hubby[0]), id(person[0])) # 2582842278064 2581907861552

hubby[1][0] = "saved"  
# 这一步相当于直接改变了只有一层的['savings', 100.00]的第一个元素,所以任何引用这个只有一层的
# list的变量,都会改变对应的值。这也是对单层list和对嵌套list要注意深拷贝和浅拷贝的原因。
print(person, hubby, wifey)
 # ['name', ['saved', 100.0]] ['Jack', ['saved', 100.0]] ['name', ['saved', 100.0]]
d = 'name'
print(id(d)) # 2581907861552
d = "jack"
print(id(d)) # 2582842106800






dic = {
       "a": ["1","2", "3"],
       "b": ["1","2", "3"],
       "c": ["1","2", "3"],
       }


c = "2"
print(id(dic["a"][1]), id(c))
# 这一步说明在python内,对于同一个不可变数据类型,都是使用的同一个地址,
# 因为是不可变数据类型,原子化操作的了,所以即使在不同的数据结构中,
# 使用的地址一样也没关系,因为它已经是不可变的了。其值不可以被改变,如果
# 不再继续用这个值,用另一个值就可以了。
a = [1,2,3]
b = a + [6]  # b是一个新的list,不是在a的基础上形成b,比如a.append这种,而是拷贝了一份a,然后再扩一个[6]
print(a, b)
[1, 2, 3] [1, 2, 3, 6]

a[0] = 10
print(a, b)

[10, 2, 3] [1, 2, 3, 6]

可以发现b的值并没有因为a[0]的改变而改变,因为b本身也是一个一维的list,只有一层
b里面的存储: [id(1), id(2), id(3), id(4)]
然后改变a之后,a由[id(1), id(2), id(3)] -> [id(10), id(2), id(3)],
并不会影响b。
也就是说,内存地址直接连接到不可变对象的,互相改来改去是没有影响的。

所以说,对于单层的list,浅拷贝看起来就直接是类似于深拷贝那种,不会互相影响。
个人理解:如果一个list中包着单层dict,也不一定就是单层list,应该是list里只包着不可变对象这种的,
才应该被理解为单层list。

这里有个工具可以可视化内存的使用:

https://pythontutor.com/render.html#mode=edit

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哇123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值