可变数据类型于不可变数据类型
可变数据类型:列表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()