浅拷贝和深拷贝

赋值操作的认知:

1  赋值是将一个对象的地址给一个变量,让该变量指向该地址。

2 修改不可变对象(str, tuple, int 等)需要开辟新空间

3 修改可变对象(list,dict, set 等)不需要开辟新空间

不可变对象赋值:

a = 100
b = a
print(id(a), id(b))
b = 200
print(id(a), id(b))

结果:

4297647584 4297647584
4297647584 4297650784

可变对象赋值:

a = {'name': '张飞龙'}
b = a
print(id(a), id(b))

b['age'] = 26
print(id(a), id(b))
print(a, b)

结果:

4301088808 4301088808
4301088808 4301088808
{'name': '张飞龙', 'age': 26} {'name': '张飞龙', 'age': 26}

浅拷贝:

概念:仅仅复制了容器中元素的地址,是对一个对象的顶层拷贝。

理解:拷贝了引用,没有拷贝内容

浅拷贝实现方式:1 使用copy模块中的copy函数

                        2 使用切片操作

                        3 使用工厂函数 (list,set,dict)

示例:

import copy

life = ['life', 26, ['Python', "Php", "JavaScript"]]

lifer = copy.copy(life)

print(id(life), id(lifer))

执行结果:

4320537224 4320558344

拷贝之后的lifer的id和之前的不同,所以浅拷贝的 时候是在为lifer开辟了新的空间

继续上面的示例

import copy

life = ['life', 26, ['Python', "Php", "JavaScript"]]

lifer = copy.copy(life)

print(id(life), id(lifer))

life[2].append('张飞龙')

print(life)
print(lifer)

执行结果:

['life', 26, ['Python', 'Php', 'JavaScript', '张飞龙']]
['life', 26, ['Python', 'Php', 'JavaScript', '张飞龙']]

分析:对life的第三项进行了修改,追加了字符串‘张飞龙’,此时我们发现两个变量都发生了改变。

继续:

import copy

life = ['life', 26, ['Python', "Php", "JavaScript"]]

lifer = copy.copy(life)

print(id(life), id(lifer))

life[2].append('张飞龙')

print(life)
print(lifer)

lifer.append('C++')
print(life)
print(lifer)

最后两行打印的结果:

['life', 26, ['Python', 'Php', 'JavaScript', '张飞龙']]
['life', 26, ['Python', 'Php', 'JavaScript', '张飞龙'], 'C++']

再加最后两行代码:

for i in life:
    print(id(i))
for i in lifer:
    print(id(i))

结果:

4301108200
4297645216
4323572488
4301108200
4297645216
4323572488
4323554336

浅拷贝的存储结果如下图,我们发现,浅拷贝实际上是将原来的数据中存储的地址进行了拷贝,存储到一块内存空间中,并且将地址赋值给了lifer

解释:

    正常情况下,由于lifer的每个元素存储的是life元素的每块空间的地址,所以当改变life元素值的时候,lifer中的元素也随之改变,因为第三个是列表,为可变类型的变量,所以不会在内存中新开辟空间,当我们在lifer中追加c++的时候,并不影响。

深拷贝:

概念:深拷贝是对于一个对象所有层次的拷贝(递归)

理解:完全拷贝了一个容器的副本,容器内部元素地址都不一样

深拷贝实现方式:1 使用copy模块中的deepcopy函数

还是同样的示例:

import copy

life = ['life', 26, ['Python', "Php", "JavaScript"]]

lifer = copy.deepcopy(life)

print(id(life), id(lifer))
for i in life:
    print(id(i))
for i in lifer:
    print(id(i))

执行结果:

4333120136 4333141256
4301108200
4297645216
4333120264
4301108200
4297645216
4333162824

内存下图


浅拷贝和深拷贝总结:

1 对于不可变类型的数据,不存在深拷贝和浅拷贝一说,因为他们都是固定的内存地址。

2 python中的对象赋值都是对对象引用的传递,就是说是对象内存地址对引用。

3 使用copy.copy()可以对对象进行浅拷贝,只复制对象中元素的地址。

4 如果需要复制一个对象中的所有元素,请使用copy.deepcopy()。

5 如果元组中只有不可变类型,则不能进行拷贝。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值