Python中赋值,深拷贝和浅拷贝

1python变量

变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的值本身。
在这里插入图片描述

2赋值

python变量赋值实际上是对象的引用
如:

list_a = [1,2,3,"hello",["python","C++"]]
list_b = list_a

此时,list_b和list_a是一样的,他们指向同一片内存,list_b不过是list_a的别名,是引用。

我们可以使用 list_b is list_a 来判断,返回true,表明他们地址相同,内容相同。也可使用id(x) for x in list_a, list_b 来查看两个list的地址。

赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了新对象的引用。也就是说,除了list_b这个名字以外,没有其它的内存开销。修改了list_a,就影响了list_b;同理,修改了list_b就影响了list_a。

3浅拷贝

浅拷贝会创建新对象,其内容是原对象的引用。

浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数
比如对上述list_a,

切片操作:list_b = list_a[:]

列表生成式: list_b = [each for each in list_a]

copy()方法:list_b=list_a.copy()

for循环:list_b=[] for i in range(len(list_a)): list_b.append(list_a[i])

工厂函数:list_b = list(list_a)

copy函数:list_b = copy.copy(list_a)

浅拷贝产生的list_b不再是list_a了,使用is可以发现他们不是同一个对象,使用id查看,发现它们也不指向同一片内存。但是当我们使用id(x) for x in list_a 和 id(x) for x in list_b 时,可以看到二者包含的元素的地址是相同的。

在这种情况下,list_a和list_b是不同的对象,修改list_b理论上不会影响list_a。比如list_b.append([4, 5])。

但是要注意,浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,在list_a中有一个嵌套的list,如果我们修改了它,情况就不一样了。

list_a[4].append(“C”)。查看list_b,你将发现list_b也发生了变化。这是因为,**你修改了嵌套的list。修改外层元素,会修改它的引用,让它们指向别的位置修改嵌套列表中的元素,列表的地址并为发生变化,指向的都是同一个位置。

4深拷贝

深拷贝只有一种形式,copy模块中的deepcopy函数。

和浅拷贝对应深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因而,它的时间和空间开销要高。

同样对list_a,若使用list_b = copy.deepcopy(list_a),再修改list_b将不会影响到list_a了。即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何关联。

代码举例:

import copy
a=[1,2,3,['a','b']]
b=a
c=copy.copy(a)
d=copy.deepcopy(a)
e=a.copy()
f=[]
for i in range(len(a)):
    f.append(a[i])
g = [each for each in a]


a.append('happy')
print('a:',a,id(a))
print('b:',b,id(b))
print('c:',c,id(c))
print('d:',d,id(d))
print('e:',e,id(e))
print('f:',f,id(f))
print('g:',g,id(g))

a.append('luck')
a[3].append(3)
print('-'*50)
print('a:',a,id(a))
print('b:',b,id(b))
print('c:',c,id(c))
print('d:',d,id(d))
print('e:',e,id(e))
print('f:',f,id(f))
print('g:',g,id(g))

输出结果:

a: [1, 2, 3, [‘a’, ‘b’], ‘happy’] 43169800
b: [1, 2, 3, [‘a’, ‘b’], ‘happy’] 43169800
c: [1, 2, 3, [‘a’, ‘b’]] 43171080
d: [1, 2, 3, [‘a’, ‘b’]] 43171016
e: [1, 2, 3, [‘a’, ‘b’]] 43170888
f: [1, 2, 3, [‘a’, ‘b’]] 43170824
g: [1, 2, 3, [‘a’, ‘b’]] 43170760


a: [1, 2, 3, [‘a’, ‘b’, 3], ‘happy’, ‘luck’] 43169800
b: [1, 2, 3, [‘a’, ‘b’, 3], ‘happy’, ‘luck’] 43169800
c: [1, 2, 3, [‘a’, ‘b’, 3]] 43171080
d: [1, 2, 3, [‘a’, ‘b’]] 43171016
e: [1, 2, 3, [‘a’, ‘b’, 3]] 43170888
f: [1, 2, 3, [‘a’, ‘b’, 3]] 43170824
g: [1, 2, 3, [‘a’, ‘b’, 3]] 43170760

参考自 https://www.cnblogs.com/work115/p/5619541.html
https://www.cnblogs.com/Black-rainbow/p/9577029.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chde2Wang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值