可变数据类型于不可变数据类型

可变数据类型:列表list和字典dict
不可变数据类型:整型int、浮点型float、字符串型string和元组tuple

这两者最本质的区别在于:,是指内存中的那块内容(值)是否可以被改变

  • 不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,就会新建了一个对象,分配相同的地址,而对于相同的值的对象,在内存中则只有一个对象,有着相同的地址。
  • 可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址不会改变,只是对应地址的内容改变或者地址发生了扩充,所以对于相同的值的不同对象,会存在多份,即每个对象都有自己的地址。

复制类型:

引用赋值:例如采用简单的 a = b
浅复制: list = copy.copy(list1), list = list1[:] 后者切片复制跟copy一样的效果,都会创建新的对象,但是只复制了第一层,也就是如果list1 里面还有个list2,那么只是简单引用了list2的地址,并没有新建一个地址
深复制:list = copy.deepcopy(list1) 这个如上,也会为list2创建新的地址,直到最里层

示例

in_planes = 3
	# 引用复制,相同的值,将会有相同的地址
	init_planes = in_planes
	input_channels = in_planes
	print(id(init_planes), id(input_channels))
	# 1821212816 1821212816
	input_channels += 2
	# string, int , float, tuple 都是不可变数据类型,如果值改变将会开辟新的地址
	print(id(input_channels))
	# 1821212880

	list1 = [1,2,3]
	list2 = [1,2,3, list1]
	list3 = copy.copy(list2) # 浅复制,只复制第一层,例如list1,属直接引用
	list4 = copy.deepcopy(list2) # 深复制,每一层都是全新的复制,有新的地址,因此修改list2 和list4任一个对另一个没有任何影响
	# modify list1
	list1[0] = 9
	print(list3)
	print(list4)
	print(id(list1), id(list3[3]), id(list4[3]))
	"""
	[1, 2, 3, [9, 2, 3]]
	[1, 2, 3, [1, 2, 3]]
	2262567893512 2262567893512 2262567893448
	"""
	#list 如果只修改元素,地址是不会变的,但是如果整个列表更新,地址会重新分配
	list1 = [6,6,6]
	list5 = list1[:]
	print(id(list1), id(list5))
	# 2138691088328 2272893405640
	# 因此,对于可变类型,如果需要分配新的空间,虽然copy对于1维可以创建新的的空间了,但还是建议用deepcopy()