深入理解python浅拷贝和深拷贝(列表,元组,字典,切片)

直接拿代码说话吧
一.浅拷贝
1.1赋值拷贝

# 关于浅拷贝
# 浅拷贝的几种
# 1 赋值拷贝
# 赋值拷贝 只拷贝了对象的引用,修改拷贝对象的值也会对原来的值有影响
					a = [1,2,3]
					b = a
					b.append(4)
					print(a)
					print(b)
					print(id(a))
					print(id(b))
					"""
					[1, 2, 3, 4]
					[1, 2, 3, 4]
					1962638078088
					1962638078088
                 """

1.2赋值拷贝的一些问题

import copy
# 浅拷贝
# 用copy模块.copy进行拷贝 只是拷贝了一个对象的顶层,里面的东西仍然拷贝的是引用
a = [1,2,3]
b = copy.copy(a)
# 在b中新增了一个元素
# 为什么不影响呢?
"""
a中有三个基本数据类型,b拷贝了a的最外层分配了一个新的空间。
里层内容拷贝的是引用,b总新增了一个基本数据与a没有关联,因为没有对a中数据进行修改
"""
		b.append(4)
		print(a)
		print(b)
		print(id(a))
		print(id(b))
		print(id(a[0]))
		print(id(b[0]))
		"""
		[1, 2, 3]
		[1, 2, 3, 4]
		2423525240968
		2423535521288
		1467575312
		1467575312
"""

1.3.1copy调用copy模块进行浅拷贝

import copy
	# 浅拷贝
	# 用copy模块.copy进行拷贝 只是拷贝了一个对象的顶层,里面的东西仍然拷贝的是引用
	a = [1,2,3]
	b = copy.copy(a)
	# 我们修改b中的值a中的值会受到影响吗?
	b[0] = 5
	print(a)
	print(b)
	print(id(a))
	print(id(b))
	print(id(a[0]))
	print(id(b[0]))
	"""
	[1, 2, 3]
	[5, 2, 3]
	2523524133000
	2523543491016
	1467575312
	1467575440
"""
# 发现没有受到影响,因为通过赋值拷贝传递了引用,此时b[0]指向值为5的对象,与a无关

1.3.2

			import copy
			# 浅拷贝
			a = [[1,2],[3,4]]
			b = copy.copy(a)
			b[0] = [1,2,3]# 与上同理不会改变原来的值
			print(a)
			print(b)
			print(id(a))
			print(id(b))
			print(id(a[0]))
			print(id(b[0]))
			'''
			[[1, 2], [3, 4]]
			[[1, 2, 3], [3, 4]]
			3235770114376
			3235761245704
			3235750965384
			3235770264072
'''

1.4copy调用copy模块进行浅拷贝

import copy
# 浅拷贝 只是考虑了顶层的列表(分配了新的存储空间)
# 列表里的东西都拷贝的是引用
	c = [1,2]
	d = [3,4]
	a = [c,d]
	b = copy.copy(a)
	c.append(5)
	print(a)
	print(b)
	print(id(a))
	print(id(b))
	print(id(a[0]))
	print(id(b[0]))
	'''
	[[1, 2, 5], [3, 4]]
	[[1, 2, 5], [3, 4]]
	1663393898696
	1663385009672
	1663374684296
	1663374684296
'''

1.5对切片的拷贝

	import copy
	# 列表的切片赋值是浅拷贝还是深拷贝?
	c = [1,2]
	d = [3,4]
	a = [c,d]
	b = a[:]
	c.append(3)
	print(a)
	print(b)
	print(id(a))
	print(id(b))
	print(id(a[0]))
	print(id(b[0]))
	'''
	[[1, 2, 3], [3, 4]]
	[[1, 2, 3], [3, 4]]
	1696674324872
	1696666469640
	1696655306888
	1696655306888
	'''
	# 发现是浅拷贝,对新列表的操作也会对原来列表影响
	# 在处理数据时,要考虑到对原数据的污染

二 深拷贝
2.1 用copy模块的deepcopy方法列表的深拷贝

	import copy
	import copy
	# 深拷贝 是递归拷贝,它不会拷贝数据的引用 而是重新分配了存储空间
	a = [[1,2],[3,4]]
	b = copy.deepcopy(a)
	b[0] = [1,2,3] # 深拷贝不会改变原来的值
	print(a)
	print(b)
	print(id(a))
	print(id(b))
	print(id(a[0]))
	print(id(b[0]))
	'''
	[[1, 2], [3, 4]]
	[[1, 2, 3], [3, 4]]
	2072156288456
	2072168263112
	2072168224904
	2072156288584 #发现id值不相同,说明重新分配了存储空间
'''

2.2 用copy模块的copy方法字典的拷贝

	import copy
	# 字典的浅拷贝
	a = {'age': 27,'name': 'zhangsan','list_age' : [12,24]}
	b = copy.copy(a)
	b['age'] = 100 # 赋值拷贝会影响
	b['list_age'].append(23) # 对字典的浅拷贝内部仍然是拷贝的引用
	print(a)
	print(b)
	print(id(a))
	print(id(b))
	2384697861968
	2384697861248


	import copy
	# 字典的深拷贝
	a = {'age': 27,'name': 'zhangsan','list_age' : [12,24]}
	b = copy.deepcopy(a)
	b['age'] = 100 # 赋值拷贝不会影响
	b['list_age'].append(23) 
	print(a)
	print(b)
	print(id(a))
	print(id(b))

三 深拷贝和浅拷贝之间的比较

import copy
a = [11,22]
b = (a,)
c = [b, ]
d = copy.copy(c)
a.append(33)
print(c)
print(d)
print(id(c))
print(id(d))
# 浅拷贝只是拷贝了最外层,里层拷贝了引用
'''
[([11, 22, 33],)]
[([11, 22, 33],)]
2866062314824
2866071179528


import copy
a = [11,22]
b = (a,)
c = [b, ]
d = copy.deepcopy(c)
a.append(33)
print(c)
print(d)
print(id(c))
print(id(d))
# 深拷贝只是拷贝了都重新分配了存储空间进行了拷贝
'''
[([11, 22, 33],)]
[([11, 22],)]
1970627436808
1970627350600

四 小结
在copy.copy方法中浅拷贝只是拷贝了顶层框架,并给顶层重新分配了存储空间,其他部分仍然拷贝的是引用
在copy.deepcopy方法中深拷贝,对所有东西进行递归拷贝,并全部重新分配了存储空间
赋值拷贝拷贝的是引用,拷贝数据和源数据的地址是相同的
对列表的切片后赋值拷贝的也是引用,对列表进行操作时要注意对原数据的污染

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值