python基础数据类型补充以及编码的进阶
一、基础数据类型补充内容
1.元组
python中元组有一个特性,元组中如果包含一个元素且没有逗号,改元组不是元组,与改元素的数据类型一致,有逗号,那么他是元组
tu = (1) print(tu,type(tu)) #1 <class 'int'> tu1 = ('alex') print(tu1,type(tu1)) #alex <class 'str'> tu2 = ([1,2,3]) print(tu2,type(tu2)) #[1, 2, 3] <class 'list'> tu = (1,) print(tu,type(tu)) #(1,) <class 'tuple'> tu1 = ('alex',) print(tu1,type(tu1)) #('alex',) <class 'tuple'> tu2 = ([1,2,3],) print(tu2,type(tu2)) #([1, 2, 3],) <class 'tuple'>
元组也有一些其他的方法:
index:通过元素找索引(可切片),找到第一个元素就返回,找不到该元素即报错。
tu = ('小白', [1, 2, 3, ], 'WuSir', '大神') print(tu.index('小白')) # 0 print(tu.index('大白')) # ValueError: tuple.index(x): x not in tuple
count: 获取某元素在元组中出现的次数
tu = ('小白', [1, 2, 3, ], 'WuSir', '大神','小白', '小白' ) print(tu.count('小白')) # 3 print(tu.count('大白')) # 0
2.列表
count: 获取某元素在列表中出现的次数
lis = ['小白', [1, 2, 3, ], 'WuSir', '大神','小白', '小白'] print(lis.count('小白')) # 3
index:通过元素找索引(可切片),找到第一个元素就返回,找不到该元素即报错。
lis = ['小白', [1, 2, 3, ], 'WuSir', '大神','小白', '小白'] print(lis.index('大神')) # 3 print(lis.index('大白')) # ValueError: '大白' is not in list
sort : 对列表进行排序
lis = [4,1,3,7,5,10,6,6] lis.sort() print(lis) # 正序[1, 3, 4, 5, 6, 6, 7, 10] lis.sort(reverse=True) print(lis) # 倒序[10, 7, 6, 6, 5, 4, 3, 1]
reverse : 反转序列
lis = ['aa',1,'bb',3] lis.reverse() print(lis) # [3, 'bb', 1, 'aa']
列表也可以相加与整数相乘:
lis = ['aa',1,'bb',3] lis2 = [1,2,3] print(lis * 2) #['aa', 1, 'bb', 3, 'aa', 1, 'bb', 3] print(lis + lis2) #['aa', 1, 'bb', 3, 1, 2, 3]
循环列表,改变列表大小的问题
在循环一个列表时的过程中,如果你要改变列表的大小(增加值,或者删除值),那么结果很可能会出错或者报错。
例:索引为奇数对应的元素删除(不能一个一个的删)
l1 = [11, 22, 33, 44, 55, 66] for index in range(0,len(l1)): if index % 2 != 0: l1.pop(index) print(l1) 直接报错 D:\pythonProject\python3\venv\Scripts\python.exe D:\pythonProject\python3\day10\s1.py Traceback (most recent call last): File "D:\pythonProject\python3\day10\s1.py", line 6, in <module> l1.pop(index) IndexError: pop index out of range
所以应该如下方法删除
#索引为奇数对应的元素删除(不能一个一个的删) #方法一:直接删除 l1 = [11, 22, 33, 44, 55, 66] del l1[1::2] print(l1) #方法二:倒序删除 l1 = [11, 22, 33, 44, 55, 66] for index in range(-len(l1),0,1): if index % 2 !=0 : l1.pop(index) print(l1) #方法三:思维置换 l1 = [11, 22, 33, 44, 55, 66] new_lis = [] for index in range(0,len(l1)): if index % 2 == 0: new_lis.append(l1[index]) l1 = new_lis print(l1)
3.dict
字典的增删改
#popitem 3.5版本之前,popitem为随机删除,3.6之后为删除最后一个,有返回值 dic = {'name': '小白', 'age': 30} ret = dic.popitem() print(ret,dic) # ('age', 30) {'name': '小白'} # update dic = {'name': '小白', 'age': 30} dic.update(sex='男',height=165) print(dic) #{'name': '小白', 'age': 30, 'sex': '男', 'height': 165} dic = {'name': '小白', 'age': 30} dic.update(([(1,'a'),(2,'b'),(3,'c')])) print(dic) #{'name': '小白', 'age': 30, 1: 'a', 2: 'b', 3: 'c'} dic1 = {'name': '小白', 'age': 30} dic2 = {'name': 'huangping', 'height':165} dic1.update(dic2) print(dic1) #{'name': 'huangping', 'age': 30, 'height': 165}
fromkeys:创建一个字典:字典的所有键来自一个可迭代对象,字典的值使用同一个值。
dic = dict.fromkeys('abcd','小白') print(dic) #{'a': '小白', 'b': '小白', 'c': '小白', 'd': '小白'} dic = dict.fromkeys([1,2,3],'小白') print(dic) #{1: '小白', 2: '小白', 3: '小白'} #这里有一个坑,就是如果通过fromkeys得到的字典的值为可变的数据类型,那么你的小心了。 dic = dict.fromkeys([1, 2, 3], []) dic[1].append(666) print(id(dic[1]),id(dic[2]),id(dic[3])) #2655183481344 2655183481344 2655183481344 print(dic) #{1: [666], 2: [666], 3: [666]}
循环字典,改变字典大小的问题
dic = {'k1':'太白','k2':'barry','k3': '白白', 'age': 18} 请将字典中所有键带k元素的键值对删除
dic = {'k1':'太白','k2':'barry','k3': '白白', 'age': 18}
for i in dic:
if 'k' in i:
del dic[i]
print(dic)
结果:
D:\pythonProject\python3\venv\Scripts\python.exe D:\pythonProject\python3\day10\s1.py
Traceback (most recent call last):
File "D:\pythonProject\python3\day10\s1.py", line 2, in <module>
for i in dic:
RuntimeError: dictionary changed size during iteration
翻译过来是:字典在循环迭代时,改变了大小。
应该如下操作
#请将字典中所有键带k元素的键值对删除 dic = {'k1':'太白','k2':'barry','k3': '白白', 'age': 18} key_list = list(dic.keys()) for i in key_list: if 'k' in i: del dic[i] print(dic) #{'age': 18}
二、数据类型间的转换问题
咱们现在学过的数据类型有:int bool str list tuple dict set ,这些数据类型之间都存在着相互转换的问题,有些转换是非常重要的,那么有些转换则基本不用,那么接下来我们学习一下比较重要的数据的转换问题。
int bool str 三者转换
# int ---> bool num1, num2 = 100, 0 print(bool(num1), bool(num2)) # True False 为0 则 False,非 0 则 True # bool ---> int t, f = True, False print(int(t), int(f)) # 1 0,True 为 1,False 为 0 # int ---> str v = 100 print(str(v)) # 100 #str ---> int 全部为数据组成的字符串才能转换 s1 = '11003' print(int(s1)) #11003 #str ---> bool s1,s2,s3 = 'aa','',None print(bool(s1),bool(s2),bool(s3)) #True False False ,非空或者非None为True,空或者None为False #bool ---> str t1 = True print(str(t1)) #True
str 和 list
# str ---> list s1 = 'aaa 小白 大神' print(s1.split()) # ['aaa', '小白', '大神'] # list ---> str 前提list元素必须都是字符串 l1 = ['aaa', '小白', '大神'] print(''.join(l1)) # aaa小白大神
list 和 set
# list ---> set s1 = [1,2,3,'aaa',2] print(set(s1)) #{1, 2, 3, 'aaa'} # set ---> list set1 = {1, 2, 3, 'aaa'} print(list(set1)) #[1, 2, 3, 'aaa']
所有的字符串都可以转换为bool值
转化为bool值为False的数据类型有:
'',0,(),{},[],set(),None
三、数据类型的总结
按照存储空间的占用(从低到搞)
数字 字符串 集合:无序,即无存索引相关信息 元组:有序,需要存索引相关信息,不可变 列表:有序,需要存索引相关信息,可变,需要处理数据得到增删改 字典:有序,需要存key与value映射的相关信息,可变,需要处理数据的增删改(3.6之后有序)
按存值个数区分
| 标量/原子类型 | 数字,字符串 |
| 容器类型 | 列表,元组,字典 |
按可变不可变区分
| 可变 | 列表,字典 |
| 不可变 | 数字,字符串,元组,布尔值 |
按访问顺序区分
| 直接访问 | 数字 |
| 顺序访问(序列类型) | 字符串,列表,元组 |
| key值访问(映射类型) | 字典 |
四、编码的进阶
编码即是密码本,编码记录的就是二进制与文字之前的对应关系
不同编码的密码本不相同,比如gbk的编码使用utf8打开就是错误或者乱码
ASCII码:包含英文字母,数字,特殊字符与01010101对应关系。
a 01000001 一个字符一个字节表示。
GBK:只包含本国文字(以及英文字母,数字,特殊字符)与0101010对应关系。
a 01000001 ascii码中的字符:一个字符一个字节表示。
中 01001001 01000010 中文:一个字符两个字节表示。
Unicode:包含全世界所有的文字与二进制0101001的对应关系。
a 01000001 01000010 01000011 00000001
b 01000001 01000010 01100011 00000001
中 01001001 01000010 01100011 00000001
UTF-8:包含全世界所有的文字与二进制0101001的对应关系(最少用8位一个字节表示一个字符)。
a 01000001 ascii码中的字符:一个字符一个字节表示。
To 01000001 01000010 (欧洲文字:葡萄牙,西班牙等)一个字符两个字节表示。
中 01001001 01000010 01100011 亚洲文字;一个字符三个字节表示。
知识点:
1. 在计算机内存中,统一使用Unicode编码,当需要将数据保存到硬盘或者需要网络传输的时候,就转换为非Unicode编码比如:UTF-8编码。
其实这个不用深入理解,他就是规定,举个例子:用文件编辑器(word,wps,等)编辑文件的时候,从文件将你的数据(此时你的数据是非Unicode(可能是UTF-8,也可能是gbk,这个编码取决于你的编辑器设置))字符被转换为Unicode字符读到内存里,进行相应的编辑,编辑完成后,保存的时候再把Unicode转换为非Unicode(UTF-8,GBK 等)保存到文件。

2. 不同编码之间,不能直接互相识别。
比如你的一个数据:‘老铁没毛病’是以utf-8的编码方式编码并发送给一个朋友,那么你发送的肯定是通过utf-8的编码转化成的二进制01010101,那么你的朋友接收到你发的这个数据,他如果想查看这个数据必须将01010101转化成汉字,才可以查看,那么此时那也必须通过utf-8编码反转回去,如果要是通过gbk编码反转,那么这个内容可能会出现乱码或者报错。
那么了解完这两点之后,咱们开始进入编码进阶的最重要的内容。
前提条件:python3x版本(python2x版本与这个不同)。
主要用途:数据的存储或者传输。
刚才咱们也说过了,在计算机内存中,统一使用Unicode编码,当需要将数据保存到硬盘或者需要网络传输的时候,就转换为非Unicode编码比如:UTF-8编码。
咱们就以网络传输为例:
好那么接下来咱们继续讨论,首先先声明一个知识点就是这里所说的'数据',这个数据,其实准确的说是以字符串(特殊的字符串)类型的数据。那么有同学就会问到,python中的数据类型很多,int bool list dict str等等,如果我想将一个列表数据通过网络传输给小明同学,不行么? 确切的说不行,你必须将这个列表转化成一个特殊的字符串类型,然后才可以传输出去,数据的存储也是如此。
那么你就清楚一些了,你想通过存储或者网络传输的数据是一个特殊的字符串类型,那么我就直接将这个字符串传出去不就行了么?比如我这有一个数据:'今晚10点吃鸡,大吉大利' 这不就是字符串类型么?我直接将这个数据通过网络发送给小明不就可以了么?不行。这里你还没有看清一个问题,就是特殊的字符串。为什么?

那么这个解决方式是什么呢?

那么这个bytes类型是个什么类型呢?其实他也是Python基础数据类型之一:bytes类型。
这个bytes类型与字符串类型,几乎一模一样,可以看看bytes类型的源码,bytes类型可以用的操作方法与str相差无几.

bytes类型也称作字节文本,他的主要用途就是网络的数据传输,与数据存储。那么有些同学肯定问,bytes类型既然与str差不多,而且操作方法也很相似,就是在字符串前面加个b不就行了,python为什么还要这两个数据类型呢?我只用bytes不行么?
如果你只用bytes开发,不方便。因为对于非ascii码里面的文字来说,bytes只是显示的是16进制。很不方便。
好,上面咱们对于bytes类型应该有了一个大致的了解,对str 与 bytes的对比也是有了对比的了解,那么咱们最终要解决的问题,现在可以解决了,那就是str与bytes类型的转换的问题。
如果你的str数据想要存储到文件或者传输出去,那么直接是不可以的,上面我们已经图示了,我们要将str数据转化成bytes数据就可以了。
str ----> bytes
# encode 称作编码:将str转换为bytes类型 s1 = '中国' b1 = s1.encode('utf-8') #转换为utf-8的bytes类型 b2 = s1.encode('gbk') #转换为gbk的bytes类型 print(s1) #中国 print(b1) #b'\xe4\xb8\xad\xe5\x9b\xbd' print(b2) #b'\xd6\xd0\xb9\xfa'
bytes ---> str
# decode 称作解码,将bytes转换为str类型 b1 = b'\xe4\xb8\xad\xe5\x9b\xbd' s1 = b1.decode('utf-8') print(s1) #中国
不同编码之间,不能直接互相识别。
如何转换:先将源编码转换为unicode,然后Unicode转换为目标编码

# utf8 ---> gbk b1 = b'\xe4\xb8\xad\xe5\x9b\xbd' s1 = b1.decode('utf-8') print(s1) # 中国 b2 = s1.encode('gbk') print(b2) # b'\xd6\xd0\xb9\xfa'
浙公网安备 33010602011771号