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'

 

 

 


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2022-12-01 16:43  小白_XiaoBai  阅读(35)  评论(0)    收藏  举报