python深浅拷贝

来讲讲python中赋值和深浅拷贝的问题

赋值

我们取两个变量x,y,并赋给他们同样的值,打印他们的id地址。

x = 3232
y = 3232
print(id(x))	#2622651027248
print(id(y))	#2622651027248
x = 'sdsd'
y = 'sdsd'
print(id(x))	#2003245593072
print(id(y))	#2003245593072

结果内存地址一样,再来看看列表

x = ['sdsd','sd']
y = ['sdsd','sd']
print(id(x))	#2340304474376
print(id(y))	#2340304474504

内存地址不同,这里不难得出,赋值给不同的变量相同的值(可变数据类型),内存地址不变,因为python有一个重用机制,对于同一个数字或字符串,python并不会开辟一块新的内存空间,而是继续用之前开辟的空间。

再试下给一个变量(字符串,数字)赋值,然后把这个变量赋给另一个变量,这里直接试两个地址是否一样。

l1 = 'python'
l2 = l1
print(id(l1)==id(l2))   # True
l1 = 'java'
print(id(l1)==id(l2))   # False

我们可以看到,如果是l1赋值给l2,两个变量指向的是同一个地址,而如果我们再给l1赋新值,地址则不同。

那给可变数据类型(字典,列表)变量赋值呢?

l1 = [1, 2, ['python', 'c', 'c++','java']]
l2 = l1
l2[1]='0'
l2[2][2]='php'
l2[2].append('ruby')
print(l1)       # [1, '0', ['python', 'c', 'php', 'java', 'ruby']]
print(id(l1)==id(l2))  # True

对列表的增改操作,l2发生了变化,而内存地址没有变化。
结论:赋值如果是数字和字符串在内存当中用的都是同一块地址,对于字典、列表等类型用的内存地址不会变化。

浅拷贝

拷贝我们需要导入copy模块

import copy
a = 123456
b = copy.copy(a)
print(id(a) == id(b))   #True

字符串的浅拷贝内存地址一样,再看看其他数据类型

import copy
a = [1, 2, ['python', 'c', 'c++','java'], {1:2, 3:4}]
b = copy.copy(a)
print(id(a) == id(b))   #False
a[2].append('ruby')
print(a)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4}]
print(b)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4}]
print(id(a[2]) == id(b[2]))     #True
a[-1].setdefault(5,6)
print(a)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}]
print(b)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}]
print(id(a[-1]) == id(b[-1]))   #True
a.append(5)
print(a)    #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}, 5]
print(b)    #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}]
print(id(a) == id(b))   #False

可以看到浅拷贝是重新开辟空间,并且只拷贝第一层,内层不拷贝,内层指向的地址都一样,而第一层的地址不同

深拷贝

字符串数字深拷贝

import copy
a = 123456
b = copy.deepcopy(a)
print(id(a) == id(b))   #True

地址一样

其他数据类型,这里用的代码和上面的基本一样:

import copy
a = [1, 2, ['python', 'c', 'c++','java'], {1:2, 3:4}]
b = copy.deepcopy(a)
print(id(a) == id(b))   #False
a[2].append('ruby')
print(a)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4}]
print(b)                #[1, 2, ['python', 'c', 'c++', 'java'], {1: 2, 3: 4}]
print(id(a[2]) == id(b[2]))     #False
a[-1].setdefault(5,6)
print(a)                #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}]
print(b)                #[1, 2, ['python', 'c', 'c++', 'java'], {1: 2, 3: 4}]
print(id(a[-1]) == id(b[-1]))   #False
a.append(5)
print(a)    #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4, 5: 6}, 5]
print(b)    #[1, 2, ['python', 'c', 'c++', 'java', 'ruby'], {1: 2, 3: 4}]
print(id(a) == id(b))   #False

内外层地址都不同,所以深拷贝在内存完完全全自己开辟了一个新空间把原来的被拷贝对象从内到外都拷贝了过来,原被拷贝对象的修改不影响拷贝的变量内的值

切片

最后说下切片,切片是浅拷贝

a = [1,2,3, [3,4,5]]
b = a[:]
a[-1].append('c')
print(a)    
print(b)
print(id(a) == id(b))
print(id(a[-1]) == id(b[-1]))

输出结果:

[1, 2, 3, [3, 4, 5, 'c']]
[1, 2, 3, [3, 4, 5, 'c']]
False
True
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值