Python深浅拷贝

目录

1 深浅拷贝理解

2 浅拷贝

2.1 使用copy. copy()函数浅拷贝

2.2 使用数据类型构造器浅拷贝

2.3 列表使用切片进行浅拷贝

2.4 赋值操作与浅拷贝的区别

3 深拷贝

4 numpy的深浅拷贝

4.1 numpy的浅拷贝

4.2 numpy的深拷贝

1 深浅拷贝理解

浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用

深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联

浅拷贝得到的新对象与原对象内部的子对象是相同的,子对象具有相同的数据与地址,修改新对象的子对象中的不可变数据类型变量时,原对象的变量值不会改变修改新对象的子对象中的可变数据类型变量时,原对象的值也会跟着改变。深拷贝之后的对象与原来的对象没有关系,只是存放的数据相同,可变数据类型的地址不同。

2 浅拷贝

2.1 使用copy. copy()函数浅拷贝

import copy
list1 = [1, 2, [1, 2, 3]]  
list2 = copy.copy(list1)
print(list2 == list1)			# True   list2与list1中的数据相同
print(list2 is list1)			# False  list2与list1是不同的对象
print(id(list1) == id(list2))	# False  list2与list1内存地址不同

对新对象list2中的不可变数据进行赋值操作(分配了新的内存空间),此时list1中对应的位置不会改变

list2[1] = 100
print(list1, list2)				
# [1, 2, [1, 2, 3]]   [1, 100, [1, 2, 3]]

print(id(list1[0]), id(list2[0]))		# 1798725265712 1798725265712
print(id(list1[1]), id(list2[1]))		# 1798725265744 1798725457360

若对新对象list2中的可变数据进行修改操作,list1中对应自变量会改变

ist2[2].append(100)
print(list1, list2)     # [1, 2, [1, 2, 3, 100]]   [1, 100, [1, 2, 3, 100]]

2.2 使用数据类型构造器浅拷贝

list1 = [1, 2, 3, [1, 2, 3]]
list2 = list(list1)  
print(list1, list2)     # [1, 2, 3, [1, 2, 3]]   [1, 2, 3, [1, 2, 3]]

# 不可变数据
list2[1] = 100
print(list1, list2)		# [1, 2, 3, [1, 2, 3]]   [1, 100, 3, [1, 2, 3]]

# 可变数据
list2[2].append(5)
print(list1, list2)		# [1, 2, 3, [1, 2, 3, 5]]   [1, 100, 3, [1, 2, 3, 5]]

2.3 列表使用切片进行浅拷贝

list1 = [1, 2, 3, [1, 2, 3]]
list2 = list1[1:]  
print(list1, list2)   # [1, 2, 3, [1, 2, 3]] [2, 3, [1, 2, 3]]

# 不可变数据
list2[1] = 100
print(list1, list2)   # [1, 2, 3, [1, 2, 3]] [2, 100, [1, 2, 3]]

# 可变数据
list2[2].append(5)
print(list1, list2)   # [1, 2, 3, [1, 2, 3, 5]] [2, 100, [1, 2, 3, 5]]

2.4 赋值操作与浅拷贝的区别

赋值是对原对象的引用,相当于给对象起了个别名,而浅拷贝是把原对象的引用复制给新对象。赋值得到的新对象,当改变其变量值时,不论是可变还是不可变数据类型的值,原对象的值也会跟着改变。

import copy
list1 = [1, 2, [1, 2, 3]]  
list2 = list1
print(list2 == list1)			# True   list2与list1中的数据相同
print(list2 is list1)			# True   list2与list1是相同的对象
print(id(list1) == id(list2))	# True   list2与list1内存地址相同

list2[1] = 100
print(list1, list2)				# [1, 100, [1, 2, 3]]   [1, 100, [1, 2, 3]]

print(id(list1[0]), id(list2[0]))		# 2433504143664 2433504143664
print(id(list1[1]), id(list2[1]))		# 2433504335312 2433504335312

list1[2].append(100)
print(list1, list2)             # [1, 100, [1, 2, 3, 100]] [1, 100, [1, 2, 3, 100]]

3 深拷贝

在python中,浅拷贝使用copy. deepcopy()函数。

import copy
list1 = [1, 2, [1, 2, 3]]  
list2 = copy.deepcopy(list1)
print(list2 == list1)			# True   list2与list1中的数据相同
print(list2 is list1)			# False  list2与list1是不同的对象
print(id(list1) == id(list2))	# False  list2与list1内存地址不同
print(id(list1), id(list2))		# 2433627089600 2433627099968

# 不可变数据
list2[1] = 100
print(list1, list2)				# [1, 2, [1, 2, 3]]   [1, 100, [1, 2, 3]]

print(id(list1[0]), id(list2[0]))		# 2433504143664 2433504143664
print(id(list1[1]), id(list2[1]))		# 2433504143696 2433504335312
print(id(list1[2]), id(list2[2]))       # 2433559239616 2433633751488	可变子对象具有不同的地址

# 可变数据
list2[2].append(100)
print(list1, list2)             # [1, 2, [1, 2, 3]] [1, 100, [1, 2, 3, 100]]

print(id(list1[0]), id(list2[0]))		# 2433504143664 2433504143664 对于不可变数据类型变量,变量值相同,地址相同
print(id(list1[1]), id(list2[1]))		# 2433504143696 2433504335312
print(id(list1[2]), id(list2[2]))       # 2433559239616 2433633751488  可变子对象的值更改后,地址不变

深拷贝后的两个对象是完全不同的对象,改变新对象中的任意变量不会对原对象造成影响。对于可变数据类型的子对象,深拷贝之后,子对象地址发生改变,但浅拷贝时不变。

4 numpy的深浅拷贝

4.1 numpy的浅拷贝

numpy中使用赋值(=)操作或者view()函数进行浅拷贝操作。

import numpy as np
a = np.array([1, 2, 3, 4])
b = a.view()
c = a
b[0] = 100
print(a, b, c)			# [100   2   3   4]  [100   2   3   4]  [100   2   3   4]

4.2 numpy的深拷贝

numpy中使用copy()函数进行浅拷贝操作。

import numpy as np
a = np.array([1, 2, 3, 4])
b = a.copy()
b[0] = 100
print(a, b)				# [1 2 3 4]  [100   2   3   4]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值