1.collections模块
Python有一些内置的数据类型,如:整型、浮点型、字符串、列表、元组、字典、集合、布尔值,除了这些之外,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple、OrderedDict等
(1)namedtuple具名元组
生成可以使用名字来访问元素内容的tuple,简单的来说就是生成有具体名字的元组
可以表示一个坐标、扑克牌等
1 # namedtuple具名元组 2 # 如想表示一个坐标p = (1,2) 3 point = namedtuple('坐标',['x','y']) 4 p = point(1,2) 5 print(p) 6 print(p.x) 7 # 表示一个三维坐标 8 point = namedtuple('坐标','x y z') # 也可以用字符串来表示,但是各字符之间要空格隔开 9 p = point(1,2,3) # 元素数量必须跟字符数量一致 10 print(p) 11 print(p.z) 12 # 表示扑克牌 13 card = namedtuple('扑克牌','花色 大小') 14 c = card('♤','2') 15 print(c) 16 print(c.花色)
(2)deque双端队列
可以从左右两侧追加和推出对象
使用list存储数据时,按索引取值很快,但是添加元素就很慢了,因为list是线性存储,数据量大的时候,出入和删除的效率很低
deque是为了高效的实现插入和删除操作的双向列表
先描述一下队列:先进先出(FIFO,first in first out)
1 # 队列 2 import queue 3 q = queue.Queue() # 生成一个队列对象 4 q.put(1) # 将1添加到队列中 5 q.put(2) # 将2添加到队列中 6 # q.put(3) 7 # 此时的第三个值被注释,未添加进去 8 print(q.get()) # 取出一个值 9 print(q.get()) # 取出第二个值 10 print(q.get()) # 取出第三个值,当值不存在时不会报错,程序会在原地等待,直到拿到这个值
deque双端队列
1 # deque双端队列 2 from collections import deque 3 l = [1,2,3] 4 q = deque(l) # 把l列表声明成一个双端队列 5 q.append('a') # 尾部添加一个a 6 print(q) 7 q.appendleft('b') # 首部添加一个b 8 print(q) 9 10 q.pop() # 尾部弹出一个值 11 print(q) 12 q.popleft() # 首部弹出一个值 13 print(q) 14 15 q.insert(1,'c') # 可以按照索引在任意位置插入值,但这应该是不被允许的 16 print(q)
(3)OrderedDict有序字典
在使用dict时,key是无序的,在对dict做迭代时,我们无法确定key的顺序
想要保持key的顺序,我们可以用OrderedDict有序字典
一个普通的字典
# 一个普通的字典 d = dict([('name','sxc'),('age',18),('pwd','123')]) # 生成一个字典 print(d) # 打印这个字典
OrderedDict有序字典
1 # OrderedDict有序字典 2 from collections import OrderedDict 3 order_d = OrderedDict([('name','sxc'),('age',18),('pwd','123')]) 4 print(order_d) # 有序的字典 5 6 order_d1 = OrderedDict() 7 order_d1['b'] = 1 8 order_d1['c'] = 2 9 order_d1['a'] = 3 10 print(order_d1) # 是按照插入的顺序排列
注意不是按照key的值排序,而是按照插入时的顺序排列
(4)defaultdict带有默认值的字典
生成一个有默认值的字典
1 # defaultdict带有默认值的字典 2 from collections import defaultdict 3 values = [11,22,33,44,55,66,77,88,99] 4 my_dict = defaultdict(list) # 默认生成的是一个空列表 5 print(my_dict['name']) # key是name,value是空列表 6 for i in values: 7 if i < 66: 8 my_dict['k1'].append(i) # 将小于66的值添加到key为k1的空列表中 9 else: 10 my_dict['k2'].append(i) # 将大于66的值添加到key为k2的空列表中 11 print(my_dict)
默认值可以是int,str,tuple等类型
1 my_dict1 = defaultdict(int) # 生成数字类型,默认是0 2 print(my_dict1['a']) 3 print(my_dict1) 4 my_dict2 = defaultdict(str) # 生成字符串类型,默认是空字符 5 print(my_dict2['b']) 6 print(my_dict2) 7 my_dict3 = defaultdict(tuple) # 生成元组类型,默认是空元组 8 print(my_dict3['c']) 9 print(my_dict3)
(5)Counter:计数器
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。
1 from collections import Counter 2 s = 'sadsafsdfsdassgssfsdfgsfasdw' 3 res = Counter(s) # 对s的字符个数的计数 4 print(res)
2.time时间模块
(1)time模块
表示时间的三种方式
在python中,通常使用三种方式来表示时间:时间戳、格式化时间、结构化时间
1.时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
2.格式化时间通常是给用户看的字符串形式,格式是:1999-12-12
3.结构化时间是以元组形式,struct_time,元组共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
1 # time时间模块 2 import time 3 print(time.time()) # 当前的时间戳 4 # 格式化时间time.strftime()表示 5 print(time.strftime('%Y-%m-%d')) # 年月日是用%加Ymd表示 6 print(time.strftime('%Y-%m-%d %H:%M:%S')) # 时分秒是用%加HMS表示 7 print(time.strftime('%Y*%m*%d %X')) #时分秒也可以用一个%X表示 8 print(time.strftime('%Y/%m')) # 中间的符号可以任意改变 9 # 结构化时间用time.localtime()表示 10 print(time.localtime()) # localtime将一个时间戳转换为当前时区的struct_time
几种格式之间的转换(转换方式如图)
1 # 时间戳-->结构化时间 2 t = time.time() # 时间戳 3 print(time.gmtime(t)) # gmtime()时间戳转为UTC伦敦时区的结构化时间 4 print(time.localtime(t)) # localtime()时间戳转为当前时区的结构化时间 5 # 结构化时间-->时间戳\格式化时间 6 t1 = time.localtime() # 结构化时间 7 print(time.mktime(t1)) # mktime()将结构化时间转为时间戳 8 print(time.strftime('%Y-%m-%d',t1)) # strftime()将结构化时间转为格式化时间,注意前面要先声明生成的格式 9 # 格式化时间-->结构化时间 10 t2 = time.strftime('%Y-%m-%d %H:%M:%S') # 格式化时间 11 print(time.strptime(t2,'%Y-%m-%d %H:%M:%S')) # strptime()将格式化时间转为结构化时间,但也要跟格式
(2)datetime模块
1 # datetime 2 import datetime 3 d = datetime.date.today() # 年月日 4 d1 = datetime.datetime.today() # 年月日时分秒 5 print(d) # 输出年月日 6 print(d1) # 输出年月日时分秒 7 print(d.year,d.month,d.day) # 分别输出年、月、日 8 print(d1.year,d1.month,d1.day,d1.hour,d1.minute,d1.second) # 分别输出年、月、日、时、分、秒 9 print(d.weekday()) # 0-6表示一周,3表示周四 10 print(d1.isoweekday()) # 1-7表示一周,4表示周四
日期的加减:
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
1 current_time = datetime.datetime.today() # 日期对象 2 timetel_t = datetime.timedelta(days = 365) # timedelta对象 3 res = current_time + timetel_t # 日期对象 4 res2 = current_time - timetel_t # 日期对象 5 print(res) # 明年 6 print(res2) # 去年
小练习:计算今天距离今年过生日还有多少天
1 birth = datetime.date(2019,12,12) # 今年生日 2 current_time = datetime.date.today() # 现在时间 3 print(birth - current_time)
3.random随机模块
随机模块的基本用法
1 # random随机模块 2 import random 3 print(random.random()) # 输出0-1之间的随机小数 4 print(random.uniform(5,10)) # 输出5-10之间的随机小数 5 print(random.randint(0,100)) # 输出0-100之间的随机整数 6 print(random.randrange(1,10,2)) # 输出1-10之间步长为2的整数(就是输出1-10之间的奇数)
随机选择返回和打乱顺序
1 # 随机选择返回 2 print(random.choice([1,2,'5',[1,3],{'name':'sxc'}])) # 随机选择列表中的任意一个元素返回,可以是数字、字符串、列表、字典 3 print(random.sample([1,2,'5',[1,3],{'name':'sxc'}],3)) # 可以指定选择列表中的几个元素返回 4 # 打乱列表顺序 5 l = [1,2,'5',[1,3],{'name':'sxc'}] 6 random.shuffle(l) 7 print(l) # 打乱顺序
练习:生成随机验证码
1 def ran(n): 2 code = '' 3 for i in range(n): 4 # 随机生成大写字母,小写字母,数字 5 ran_A = chr(random.randint(65,90)) 6 ran_a = chr(random.randint(97,122)) 7 ran_num = str(random.randint(0,9)) 8 # 添加进列表,随机生成一个验证码的某一位,直至生成一个需要的位数的验证码 9 code += random.choice([ran_a,ran_A,ran_num]) 10 return code # 返回验证码 11 12 print(ran(4)) # 生成一个4位验证码 13 print(ran(5)) # 生成一个5位验证码
4.os模块
os模块是与操作系统交互的一个接口
模拟用户打开文件
1 import os 2 BASE_DIR = os.path.dirname(__file__) # 回到根目录 3 MOVIE_DIR = os.path.join(BASE_DIR,'学习视频') # 进入子文件夹 4 movie_list = os.listdir(MOVIE_DIR) # 把字文件夹中的文件用列表的形式排列 5 while True: 6 for i,j in enumerate(movie_list,1): 7 print(i,j) 8 choice = input('请输入你想看的学习视频>>>:').strip() 9 if choice.isdigit(): # 判断输入是否为数字 10 choice = int(choice) 11 if choice <= 6 and choice >0: # 判断输入的数字是否在列表中 12 target_file = movie_list[choice-1] # 在列表中获取用户想看的文件名 13 target_path = os.path.join(MOVIE_DIR,target_file) # 拼接为绝对路径 14 with open(target_path,'r',encoding='utf-8') as f: 15 print(f.read()) 16 break
os模块的其他常用操作
1 os.mkdir('精选视频') # 自动创建新文件夹 2 os.rmdir('精选视频') # 删除文件夹,只能删除空文件夹 3 print(os.path.exists(r'H:\老男孩培训学习\自编的代码\学习视频\吉泽老师.txt')) # 判断文件是否存在 4 print(os.path.exists(r'H:\老男孩培训学习\自编的代码\学习视频')) # 判断文件夹是否存在 5 print(os.path.isfile(r'H:\老男孩培训学习\自编的代码\学习视频')) # 不能判断文件夹 6 print(os.path.isfile(r'H:\老男孩培训学习\自编的代码\学习视频\吉泽老师.txt')) # 只能判断文件 7 8 print(os.getcwd()) # 获取当前工作目录 9 print(os.chdir(r'H:\老男孩培训学习\自编的代码\学习视频')) # 改变当前的目录,相当于终端的cd 10 print(os.getcwd()) 11 12 # 获取文件大小 13 print(os.path.getsize(r'H:\老男孩培训学习\自编的代码\学习视频\吉泽老师.txt')) # 获取文件的字节大小 14 with open(r'H:\老男孩培训学习\自编的代码\学习视频\吉泽老师.txt',encoding='utf-8') as f: 15 print(len(f.read())) # 获取文件的字符长度
5.sys模块
sys模块是与python解释器交互的一个接口
一些sys模块的基本用法
1 # sys模块 2 import sys 3 # sys.path.append() # 将某个路径添加到环境变量中 4 print(sys.platform) # 查看电脑的版本(不准确) 5 print(sys.version) # 查看python解释器的版本
sys.argv,可以做一个终端用户身份认证功能
1 # 终端判断用户是否有使用该文件的权利(终端的身份验证功能) 2 print(sys.argv) # 终端输出的是一个列表 3 if len(sys.argv) < 2: 4 print('请输入用户名和密码') 5 else: 6 username = sys.argv[1] 7 pwd = sys.argv[2] 8 if username == 'sxc' and pwd == '123': 9 print('欢迎进入') 10 # 输入该文件的代码逻辑 11 else: 12 print('请输入正确的用户名和密码')
6.序列化模块
什么叫序列化
将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化
写入文件必须是字符串形式,而基于网络传播必须是二进制模式
序列化:其他数据转为字符串的形式
反序列化:字符串转为其他数据类型
比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给? 现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。 但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? 没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串, 但是你要怎么把一个字符串转换成字典呢? 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。 eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。 BUT!强大的函数有代价。安全性是其最大的缺点。 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。 而使用eval就要担这个风险。 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
序列化的目的
1.以某种存储形式使自定义对象持久化
2.将对象从一个地方传递到另一个地方
3.使程序更具维护性
序列化一共有两个模块
(1)json模块
json用于字符串和python数据类型之间进行转换
特点:所有的语言都支持json格式
支持的数据类型很少,字符串,数字类型,列表,字典,元组(转为列表),布尔值
dumps:序列化,将其他数据类型转为json格式的字符串
loads:反序列化,将json格式的字符串转为其他数据类型
dumps和loads
1 import json 2 d = {'name':'sxc'} 3 res = json.dumps(d) # 序列化,将字典d转为json格式的字符串 4 print(res,type(res)) # json格式的字符串,内部的字符串是""双引号,内部其实是'{"name":"sxc"}' 5 res1 = json.loads(res) # 反序列化,将json格式的字符串 6 print(res1,type(res1))
dump和load(可以直接序列化存入文件和直接反序列化并在文件中打开)
1 d = {'name':'sxc'} 2 with open(r'userinfo.txt','w',encoding='utf-8') as f: 3 json.dump(d,f) # 序列化,数据类型转为json格式字符串并自动写入文件 4 # json.dump(d,f) # 多次存入会放在同一行 5 with open(r'userinfo.txt','r',encoding='utf-8') as f: 6 res1 = json.load(f) # 反序列化,从文件中拿出json格式的字符串并转为对应的数据类型 7 print(res1,type(res1)) # 不能一次读取多个或者多行,会报错
注意:多次存入会放在同一行,但是取的时候识别不出来会产生报错
多次序列化存入文件和多次反序列化读出文件(通过换行符的加入,反序列化每行的内容)
1 d = {'name':'sxc'} 2 with open(r'userinfo.txt','w',encoding='utf-8') as f: 3 json1 = json.dumps(d) 4 json2 = json.dumps(d) # 多次序列化 5 f.write('%s\n'%json1) 6 f.write('%s\n'%json2) # 将序列化的文件写入并加入换行符 7 8 with open(r'userinfo.txt','r',encoding='utf-8') as f: 9 for line in f: # 循环反序列化并读取每行的内容 10 res = json.loads(line) 11 print(res)
补充:在序列化时显示中文
1 d1 = {'name':'朱质建'} 2 print(json.dumps(d1)) # 在序列化时,所有非ASCII码字符显示为\uXXXX序列 3 print(json.dumps(d1,ensure_ascii=False)) # ensure_ascii=False可以显示出中文
(2)pickle模块
pickle用于python特有的类型和python的数据类型之间进行转换
特点:只支持python一种语言
可以支持python中的所有数据类型
将数据类型转换为二进制模式,在文件中需要用b模式打开
dumps和loads
1 # pickle模块 2 import pickle 3 d = {'name':'sxc'} 4 res = pickle.dumps(d) # 序列化 5 print(res,type(res)) # 输出的是二进制形式 6 res1 = pickle.loads(res) # 反序列化 7 print(res1,type(res1)) # 还原了字典d
dump和load
1 # 用pickle存入文件的时候必须是b模式,因为他输出的是二进制形式 2 d = {'name':'sxc'} 3 with open(r'username.txt','wb') as f: # 写要用wb模式,并且不能编码 4 pickle.dump(d,f) 5 with open(r'username.txt','rb') as f: # 读要用rb模式 6 res = pickle.load(f) 7 print(res,type(res))
7.subprocess模块
subprocess模块允许我们启动一个新进程,并连接到他们的输入/输出/或者错误,从而获取返回值
1.类似于用户远程操作你的电脑
2.输入相应命令发送给电脑某个程序
3.获取用户的命令,使用subprocess模块执行用户命令
4.将执行命令基于网络返回给用户
1 # subprocess模块 2 """ 3 1.用户通过网络连接上了你的这台电脑 4 2.用户输入相应的命令 基于网络发送给了你这台电脑上某个程序 5 3.获取用户命令 里面subprocess执行该用户命令 6 4.将执行结果再基于网络发送给用户 7 这样就实现 用户远程操作你这台电脑的操作 8 """ 9 import subprocess 10 while True: 11 cmd = input('输入的命令>>>:') # 远程输入命令 12 obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 13 print('正确命令返回的结果stdout',obj.stdout.read().decode('gbk')) # 输入正确的命令返回的结果 14 print('错误的命令返回的提示信息',obj.stderr.read().decode('gbk')) # 输入错误的命令返回的结果
来源:https://www.cnblogs.com/sxchen/p/11210772.html