Loading... # python可变、不可变数据类型 `用于记录python数据类型` python我个人常用的数据就是数字、字符串、元组、列表、集合、字典,分为**可变类型**和**不可变类型**。 --- # 一、什么是可变和不可变的数据类型? 可变就是说在相同内存地址的内容可以发生改变,反之,不可变类型就是相同地址的内容不能被修改。 # 二、不可变类型 ## 1.数字 ```python #数字 a=1.0 print(id(a), type(a)) a=2.0 print(id(a), type(a)) ``` **输出:** ```python 2633529434384 <class 'float'> 2633566302832 <class 'float'> ``` 本以为数字相同变量,重新赋值后还在相同地方,其实他已经修改了地址了。。不过不影响使用就是了。 ## 2.字符 ```python #字符 a="a" print(id(a), type(a)) a="b" print(id(a), type(a)) ``` **输出:** ```python 2633529434384 <class 'float'> 2633566302832 <class 'float'> ``` 字符也是另外的地址了 ## 3.元组 ```python #元组 #元组可以当作是没有类型的数组,不可被改变 a=(1,2) print(id(a), type(a)) a=(3,4) print(id(a), type(a)) a[0]=0 #报错,不能被重新赋值 ``` **输出:** ```python 2633566244032 <class 'tuple'> 2633566657280 <class 'tuple'> --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In [7], line 7 5 a=(3,4) 6 print(id(a), type(a)) ----> 7 a[0]=0 TypeError: 'tuple' object does not support item assignment ``` 字符也是另外的地址了 # 三、可变类型 ## 4.列表 ```python ##列表 #元组用小括号 a=(1,2) #列表用中括号 b=[3,2] print(b) #重新赋值 #a[0]=3 #出错 b[0]=1 #可运行 print(b) ``` **输出:** ```python [3, 2] [1, 2] ``` 但是元组和列表使用numpy转成数据就相同了。我们在正常使用中通常是用到numpy的,所以是没问题的。 ```python #转成numpy就一样了 #元组转numpy数组 import numpy as np c=np.array(a,dtype=np.uint8) d=np.array(b,dtype=np.uint8) print("a:",a) print("b:",b) print("c:",c) print("d:",d) print(c==d) ``` **输出:** ```python a: (1, 2) b: [1, 2] c: [1 2] d: [1 2] [ True True] ``` ### 需要注意的点 由于列表是可变类型,因此如果使用浅拷贝会改变原始值、目标值。 ```c b=[3,2] #原始值 print(b) c=b #浅拷贝 C为目标值 c[0]=1 print(b) #目标值改变导致原始值改变 print("//") print(c) b[0]=4 print(c) #原始值改变导致目标值改变 ``` **输出:** ```python [3, 2] [1, 2] // [1, 2] [4, 2] ``` 若不想改变可用**深拷贝** ```python ##深拷贝互不影响 import copy b=[3,2] #原始值 print(b) c=copy.deepcopy(b) #深拷贝 C为目标值 c[0]=1 print(b) #目标值改变,不影响原始值 print("//") print(c) b[0]=4 print(c) #原始值改变,不影响目标值 ``` **输出:** ```python [3, 2] [3, 2] // [1, 2] [1, 2] ``` ## 5.集合 ```python # 集合 set1 = {1, 2, 3, '123'} print("集合:", set1, "内存地址:", id(set1), "\t", "数据类型:", type(set1), "\t") # 给set1删除一个元素 set1.remove(2) print("集合:", set1, "内存地址:", id(set1), "\t", "数据类型:", type(set1), "\t") ``` **输出:** ```python 集合: {'123', 1, 2, 3} 内存地址: 2635583510784 数据类型: <class 'set'> 集合: {'123', 1, 3} 内存地址: 2635583510784 数据类型: <class 'set'> ``` ## 5.字典 ```python #字典 #采用键值对(key-value)的形式存储数据 dict1 = {'name': 'abc', 'age': 18} print("字典:", dict1, "内存地址:", id(dict1), "数据类型:", type(dict1)) #重新赋值 dict1['sex'] = 'man' print("字典:", dict1, "内存地址:", id(dict1), "数据类型:", type(dict1)) ``` 注意事项与列表相同 **输出:** ```python 字典: {'name': 'abc', 'age': 18} 内存地址: 2635718986560 数据类型: <class 'dict'> 字典: {'name': 'abc', 'age': 18, 'sex': 'man'} 内存地址: 2635718986560 数据类型: <class 'dict'> ``` 注意事项与列表相同 ## 6.补充 -深拷贝和浅拷贝 深拷贝:对原对象的地址的拷贝,新拷贝了一份与原对象不同的地址的对象,修改对象中的任何值,都不会改变深拷贝的对象的值。 浅拷贝:对原对象的值的拷贝,地址仍是一个指针指向原对象的地址,浅拷贝或者原对象的值发生变化,那原对象和浅拷贝对象的值都会随着被改变。 浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用 深拷贝(深度克隆):不仅复制对象的基本类,同时也复制原对象的对象,完全是新对象产生的 ```python copy.copy #浅拷贝 copy.deepcopy #深拷贝 ``` --- # 总结 个人学习中想要记录的一些东西, 不可变数据类型中的数字和字符,对日常使用无影响,元组只要记住不可变就行,因为不可被串改,因此可作为**记录**使用。若想使用能改变的就用列表或转成numpy数组。 可变数据类型记住浅拷贝的时候,原始值和目标值改变一个,另外一个也会发生改变。 最后修改:2025 年 02 月 22 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏