python-常用模块
re模块
re模块的常用用法
import re # 字符串 # 匹配 # findall ***** # ret = re.findall('\d+','19874ashfk01248') # print(ret) # 参数 返回值类型:列表 返回值个数:1 返回值内容:所有匹配上的项 # ret1 = re.findall('\s+','19874ashfk01248') # print(ret1) # search ***** # ret2 = re.search('\d+','@$19874ashfk01248') # print(ret2) # 返回值类型: 正则匹配结果的对象 返回值个数:1 如果匹配上了就返回对象 # if ret2:print(ret2.group()) # 返回的对象通过group来获取匹配到的第一个结果 # ret3 = re.search('\s+','19874ashfk01248') # print(ret3) # 返回值类型: None 如果没有匹配上就是None # match ** # ret4 = re.match('\d+','19874ashfk01248') # print(ret4) # ret5 = re.match('\d+','%^19874ashfk01248') # print(ret5) # 替换 replace # sub *** # print('replace789,24utdeedeeeeshf'.replace('e','H',3)) # ret = re.sub('\d+','H','replace789nbc2xcz392zx') # print(ret) # ret = re.sub('\d+','H','replace789nbc2xcz392zx,48495',1) # print(ret) # subn *** # ret = re.subn('\d+','H','replace789nbc2xcz392zx') # print(ret) # 切割 # split *** # print('alex|83|'.split('|')) # ret = re.split('\d+','alex83egon20taibai40') # print(ret) # 进阶方法 - 爬虫\自动化开发 # compile ***** 时间效率 # re.findall('-0\.\d+|-[1-9]+(\.\d+)?','alex83egon20taibai40') --> python解释器能理解的代码 --> 执行代码 # ret = re.compile('-0\.\d+|-[1-9]\d+(\.\d+)?') # res = ret.search('alex83egon-20taibai-40') # print(res.group()) # 节省时间 : 只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率 # finditer ***** 空间效率 # print(re.findall('\d','sjkhkdy982ufejwsh02yu93jfpwcmc')) # ret = re.finditer('\d','sjkhkdy982ufejwsh02yu93jfpwcmc') # for r in ret: # print(r.group())
random模块
random模块常用方法
import random # 随机 : 在某个范围内取到每一个值的概率是相同的 # 随机小数 # print(random.random()) # 0-1之内的随机小数 # print(random.uniform(1,5)) # 任意范围之内的随机小数 # 随机整数 ***** # print(random.randint(1,2)) # [1,2] 包含2在内的范围内随机取整数 # print(random.randrange(1,2)) # [1,2)不包含2在内的范围内随机取整数 # print(random.randrange(1,10,2)) # [1,10)不包含10在内的范围内随机取奇数 # 随机抽取 # 随机抽取一个值 # lst = [1,2,3,'aaa',('wahaha','qqxing')] # ret = random.choice(l) # print(ret) # 随机抽取多个值 # ret = random.sample(lst,2) # print(ret) # 打乱顺序 在原列表的基础上做乱序 # lst = [1,2,3,'aaa',('wahaha','qqxing')] # random.shuffle(lst) # print(lst) # 抽奖 \ 彩票 \发红包 \验证码 \洗牌
# 生成随机验证码 # 4位数字的 import random # 0-9 # 基础版本 # code = '' # for i in range(4): # num = random.randint(0,9) # code += str(num) # print(code) # 函数版本 # def rand_code(n=4): # code = '' # for i in range(n): # num = random.randint(0,9) # code += str(num) # return code # # print(rand_code()) # print(rand_code(6)) # 6位 数字+字母 # print(chr(97)) # print(chr(122)) # import random # 基础版 # code = '' # for i in range(6): # rand_num = str(random.randint(0,9)) # rand_alph = chr(random.randint(97,122)) # rand_alph_upper = chr(random.randint(65,90)) # atom_code = random.choice([rand_num,rand_alph,rand_alph_upper]) # code += atom_code # print(code) # 函数版 # def rand_code(n=6): # code = '' # for i in range(n): # rand_num = str(random.randint(0,9)) # rand_alph = chr(random.randint(97,122)) # rand_alph_upper = chr(random.randint(65,90)) # atom_code = random.choice([rand_num,rand_alph,rand_alph_upper]) # code += atom_code # return code # # ret = rand_code() # print(ret) # 数字/数字+字母 # def rand_code(n=6 , alph_flag = True): # code = '' # for i in range(n): # rand_num = str(random.randint(0,9)) # if alph_flag: # rand_alph = chr(random.randint(97,122)) # rand_alph_upper = chr(random.randint(65,90)) # rand_num = random.choice([rand_num,rand_alph,rand_alph_upper]) # code += rand_num # return code # # ret = rand_code(n = 4) # print(ret) # ***** 永远不要创建一个和你知道的模块同名的文件名 #函数 : 发红包 : 200块钱 , 10个
time模块
表示时间的三种方式
- 时间戳时间,格林威治时间,float数据类型 给机器用的
- 结构化时间,时间对象 上下两种格式的中间状态
- 格式化时间,字符串时间,str数据类型 给人看的
%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身 python中时间日期格式化符号:
python中表示时间的几种格式:
#导入时间模块 >>>import time #时间戳 >>>time.time() 1500875844.800804 #时间字符串 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 13:54:37' >>>time.strftime("%Y-%m-%d %H-%M-%S") '2017-07-24 13-55-04' #时间元组:localtime将一个时间戳转换为当前时区的struct_time time.localtime() time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=59, tm_sec=37, tm_wday=0, tm_yday=205, tm_isdst=0)
几种格式之间的转换
#几种格式之间的转换 # print(time.time()) # print(time.localtime(1500000000)) # print(time.localtime(2000000000)) # time_obj = time.localtime(3000000000) # format_time = time.strftime('%y-%m-%d %H:%M:%S',time_obj) # print(format_time) # 2008-8-8 # struct_time = time.strptime('2008-8-8','%Y-%m-%d') # print(struct_time) # print(time.mktime(struct_time)) # 计算本月一号的时间戳时间 # 结构化时间 # struct_time = time.localtime() # struct_time = time.strptime('%s-%s-1'%(struct_time.tm_year,struct_time.tm_mon),'%Y-%m-%d') # print(time.mktime(struct_time)) # 格式化时间 # ret = time.strftime('%Y-%m-1') # struct_time = time.strptime(ret,'%Y-%m-%d') # print(time.mktime(struct_time))
datetime模块
datetime.now() # 获取当前datetime
datetime.utcnow() # 获取当前格林威治时间
from datetime import datetime #获取当前本地时间 a=datetime.now() print('当前日期:',a) #获取当前世界时间 b=datetime.utcnow() print('世界时间:',b)
2.datetime(2017, 5, 23, 12, 20) # 用指定日期时间创建datetime
from datetime import datetime #用指定日期创建 c=datetime(2017, 5, 23, 12, 20) print('指定日期:',c)
3.将以下字符串转换成datetime类型:
'2017/9/30'
'2017年9月30日星期六'
'2017年9月30日星期六8时42分24秒'
'9/30/2017'
'9/30/2017 8:42:50 '
from datetime import datetime d=datetime.strptime('2017/9/30','%Y/%m/%d') print(d) e=datetime.strptime('2017年9月30日星期六','%Y年%m月%d日星期六') print(e) f=datetime.strptime('2017年9月30日星期六8时42分24秒','%Y年%m月%d日星期六%H时%M分%S秒') print(f) g=datetime.strptime('9/30/2017','%m/%d/%Y') print(g) h=datetime.strptime('9/30/2017 8:42:50 ','%m/%d/%Y %H:%M:%S ') print(h) 时间字符串格式化
4.将以下datetime类型转换成字符串:
2017年9月28日星期4,10时3分43秒
Saturday, September 30, 2017
9/30/2017 9:22:17 AM
September 30, 2017
from datetime import datetime i=datetime(2017,9,28,10,3,43) print(i.strftime('%Y年%m月%d日%A,%H时%M分%S秒')) j=datetime(2017,9,30,10,3,43) print(j.strftime('%A,%B %d,%Y')) k=datetime(2017,9,30,9,22,17) print(k.strftime('%m/%d/%Y %I:%M:%S%p')) l=datetime(2017,9,30) print(l.strftime('%B %d,%Y')) 时间字符串格式化
5.用系统时间输出以下字符串:
今天是2017年9月30日
今天是这周的第?天
今天是今年的第?天
今周是今年的第?周
今天是当月的第?天
from datetime import datetime #获取当前系统时间 m=datetime.now() print(m.strftime('今天是%Y年%m月%d日')) print(m.strftime('今天是这周的第%w天')) print(m.strftime('今天是今年的第%j天')) print(m.strftime('今周是今年的第%W周')) print(m.strftime('今天是当月的第%d天'))
sys模块
sys模块是与python解释器交互的一个接口
sys.modules sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称
OS模块
os模块是与操作系统交互的一个接口
os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.system("bash command") 运行shell命令,直接显示 os.popen("bash command).read() 运行shell命令,获取执行结果 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.path os.path.abspath(path) 返回path规范化的绝对路径os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
logging模块
- 日志格式的规范
- 操作的简化
- 日志的分级管理
函数式简单配置
import logging logging.debug('debug message') # 调式模式 logging.info('info message') # 基础信息 logging.warning('warning message') #警告 logging.error('error message') # 错误 logging.critical('critical message') # 严重错误
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息
灵活配置日志级别,日志格式,输出位置:
import logging
file_handler = logging.FileHandler(filename='test.log', mode='a', encoding='utf-8',)
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers=[file_handler,],
level=logging.ERROR
)
logging.error('你好')
format='%(asctime)s #时间 %(filename)s #错误的文件 [line:%(lineno)d] # 哪一行的错误 %(levelname)s # 什么级别的错误 %(message)s', # 错误信息
参数配置
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息
日志切割
logger对象配置
# logger对象的形式来操作日志文件
# 创建一个logger对象
# 创建一个文件管理操作符
# 创建一个屏幕管理操作符
# 创建一个日志输出的格式
# 文件管理操作符 绑定一个 格式
# 屏幕管理操作符 绑定一个 格式
# logger对象 绑定 文件管理操作符
# logger对象 绑定 屏幕管理操作符
import logging
# 创建一个logger对象
logger = logging.getLogger()
# 创建一个文件管理操作符
fh = logging.FileHandler('logger.log',encoding='utf-8')
# 创建一个屏幕管理操作符
sh = logging.StreamHandler()
# 创建一个日志输出的格式
format1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 文件管理操作符 绑定一个 格式
fh.setFormatter(format1)
# 屏幕管理操作符 绑定一个 格式
sh.setFormatter(format1)
logger.setLevel(logging.DEBUG)
# logger对象 绑定 文件管理操作符
# logger.addHandler(fh)
# logger对象 绑定 屏幕管理操作符
logger.addHandler(sh)
logger.debug('debug message') # 调试模式
logger.info('我的信息') # 基础信息
logger.warning('warning message') # 警告
logger.error('error message') # 错误
logger.critical('critical message')# 严重错误
hashlib模块
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。
什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:
import hashlib md5 = hashlib.md5() md5.update('how to use md5 in python hashlib?') print md5.hexdigest() 计算结果如下: d26a53750bc40b38b65a520292f69306
如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
md5 = hashlib.md5() md5.update('how to use md5 in ') md5.update('python hashlib?') print md5.hexdigest()
MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:
import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in ') sha1.update('python hashlib?') print sha1.hexdigest()
SHA1,通常用一个40位的16进制字符串表示,算法相对复杂 计算速度也慢, 比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。
摘要算法应用
1.登录的密文验证
密码不能解密,但可以撞库
# 数据库 - 撞库 # 111111 --> 结果 # 666666 # 123456 # alex3714 --> aee949757a2e698417463d47acac93df # s1 = '123456' # md5_obj = hashlib.md5() # md5_obj.update(s1.encode('utf-8')) # res = md5_obj.hexdigest() # print(res,len(res),type(res))
加盐
# 加盐 # wind3714 d3cefe8cdd566977ec41566f1f11abd9 # md5_obj = hashlib.md5('任意的字符串作为盐'.encode('utf-8')) # md5_obj.update(s1.encode('utf-8')) # res = md5_obj.hexdigest() # print(res,len(res),type(res)) # wind登录 alex3714|d3cefe8cdd566977ec41566f1f11abd9 # wind|d3cefe8cdd566977ec41566f1f11abd9 # 张三|d3cefe8cdd566977ec41566f1f11abd8 123456 # 鞠莹莹|d3cefe8cdd566977ec41566f1f11abd8 123456
动态加盐
# 遇到恶意用户 注册500个账号,我们采用动态加盐 # 张三|123456 '任意的字符串作为盐'.encode('utf-8') d3cefe8cdd566977ec41566f1f11abd8 # 李四|111111 # eee|alex3714 # 动态加盐 # username = input('username : ') # passwd = input('password : ') # md5obj = hashlib.md5(username.encode('utf-8')) # md5obj.update(passwd.encode('utf-8')) # print(md5obj.hexdigest()) # ee838c58e5bb3c9e687065edd0ec454f
2.文件的一致性校验
# md5_obj = hashlib.md5() # with open('5.序列化模块_shelve.py','rb') as f: # md5_obj.update(f.read()) # ret1 = md5_obj.hexdigest() # # md5_obj = hashlib.md5() # with open('5.序列化模块_shelve.py.bak','rb') as f: # md5_obj.update(f.read()) # ret2 = md5_obj.hexdigest() # print(ret1,ret2)
大文件的一致性校验
# 写成一个函数 # 参数 : 文件1的路径,文件2的路径,默认参数 = 1024000 # 计算这两个文件的md5值 # 返回它们的一致性结果 T/F 1 import hashlib 2 md5_obj = hashlib.md5() 3 import os 4 filesize = os.path.getsize('filename') #文件大小 5 f = open('filename','rb') 6 while filesize>0: 7 if filesize > 1024: 8 content = f.read(1024) 9 filesize -= 1024 10 else: 11 content = f.read(filesize) 12 filesize -= filesize 13 md5_obj.update(content) 14 # for line in f: 15 # md5_obj.update(line.encode('utf-8')) 16 md5_obj.hexdigest() 文件校验(检测文件改变了没)
序列化模块
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
json
Json模块提供了四个功能:dumps、dump、loads、load
import json # json格式的限制1,json格式的key必须是字符串数据类型 # json格式中的字符串只能是"" # 如果是数字为key,那么dump之后会强行转成字符串数据类型 # dic = {1:2,3:4} # str_dic = json.dumps(dic) # print(str_dic) # new_dic = json.loads(str_dic) # print(new_dic) # json是否支持元组,对元组做value的字典会把元组强制转换成列表 # dic = {'abc':(1,2,3)} # str_dic = json.dumps(dic) # print(str_dic) # new_dic = json.loads(str_dic) # print(new_dic) # json是否支持元组做key,不支持 # dic = {(1,2,3):'abc'} # str_dic = json.dumps(dic) # 报错 # 对列表的dump # lst = ['aaa',123,'bbb',12.456] # with open('json_demo','w') as f: # json.dump(lst,f) # with open('json_demo') as f: # ret = json.load(f) # print(ret) # 能不能多次dump数据到文件里,可以多次dump但是不能load出来了 # dic = {'abc':(1,2,3)} # lst = ['aaa',123,'bbb',12.456] # with open('json_demo','w') as f: # json.dump(lst,f) # json.dump(dic,f) # with open('json_demo') as f: # ret = json.load(f) # print(ret) # 想dump多个数据进入文件,用dumps # dic = {'abc':(1,2,3)} # lst = ['aaa',123,'bbb',12.456] # with open('json_demo','w') as f: # str_lst = json.dumps(lst) # str_dic = json.dumps(dic) # f.write(str_lst+'\n') # f.write(str_dic+'\n') # with open('json_demo') as f: # for line in f: # ret = json.loads(line) # print(ret) # 中文格式的 ensure_ascii = False # dic = {'abc':(1,2,3),'country':'中国'} # ret = json.dumps(dic,ensure_ascii = False) # print(ret) # dic_new = json.loads(ret) # print(dic_new) # with open('json_demo','w',encoding='utf-8') as f: # json.dump(dic,f,ensure_ascii=False) # json的其他参数,是为了用户看的更方便,但是会相对浪费存储空间 # import json # data = {'username':['李华','二愣子'],'sex':'male','age':16} # json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False) # print(json_dic2) # set不能被dump/dumps
pickle
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)
# pickle dic = {1:(12,3,4),('a','b'):4} import pickle # dump的结果是bytes,dump用的f文件句柄需要以wb的形式打开,load所用的f是'rb'模式 # 支持几乎所有对象的序列化 # 对于对象的序列化需要这个对象对应的类在内存中 # 对于多次dump/load的操作做了良好的处理 # pic_dic = pickle.dumps(dic) # print(pic_dic) # bytes类型 # new_dic = pickle.loads(pic_dic) # print(new_dic) # pickle支持几乎所有对象的 # class Student: # def __init__(self,name,age): # self.name = name # self.age = age # # alex = Student('alex',83) # ret = pickle.dumps(alex) # 小花 = pickle.loads(ret) # print(小花.name) # print(小花.age) # class Student: # def __init__(self,name,age): # self.name = name # self.age = age # # alex = Student('alex',83) # with open('pickle_demo','wb') as f: # pickle.dump(alex,f) # with open('pickle_demo','rb') as f: # 旺财 = pickle.load(f) # print(旺财.name) # 学员选课系统 pickle模块来存储每个学员的对象 # with open('pickle_demo','wb') as f: # pickle.dump({'k1':'v1'}, f) # pickle.dump({'k11':'v1'}, f) # pickle.dump({'k11':'v1'}, f) # pickle.dump({'k12':[1,2,3]}, f) # pickle.dump(['k1','v1','l1'], f) # with open('pickle_demo','rb') as f: # while True: # try: # print(pickle.load(f)) # except EOFError: # break
既然pickle如此强大,为什么还要学json呢?
这里我们要说明一下,json是一种所有的语言都可以识别的数据结构。
如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。
但是如果我们用pickle进行序列化,其他语言就不能读懂这是什么了~
所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用json模块
但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python对这个数据进行反序列化的话,那么就可以使用pickle
collections模块
数据类型的扩展模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
什么是队列?
# 先进先出 # import queue # q = queue.Queue() # print(q.qsize()) # q.put(1) # q.put('a') # q.put((1,2,3)) # q.put(({'k':'v'})) # print(q.qsize()) # print('q : ',q) # print('get : ',q.get()) # print(q.qsize())
deque 双端队列
# from collections import deque # dq = deque() # dq.append(2) # dq.append(5) # dq.appendleft('a') # dq.appendleft('b') # print(dq) # # print(dq.pop()) # # print(dq) # # print(dq.popleft()) # # print(dq) # print(dq.remove('a')) # print(dq.insert(2,'123')) # print(dq)
在insert remove的时候 deque的平均效率要高于列表
列表根据索引查看某个值的效率要高于deque
append 和pop对于列表的效率是没有影响
Counter计数器
1. 对字符串\列表\元祖\字典进行计数,返回一个字典类型的数据,键是元素,值是元素出现的次数
举例:
from collections import Counter
s = "hello-python-hello-world"
a = Counter(s)
print(a)
# 结果
Counter({'-': 3, 'd': 1, 'e': 2, 'h': 3, 'l': 5, 'n': 1, 'o': 4, 'p': 1, 'r': 1, 't': 1, 'w': 1, 'y': 1})
2. most_common(n) (统计出现最多次数的n个元素)
举例:
print(a.most_common(3))
# 结果
[('l', 5), ('o', 4), ('h', 3)] 出现次数最多的三个元素
3. elements (返回一个Counter计数后的各个元素的迭代器)
举例:
for i in a.elements():
print(i, end="")
# 结果:
hhheellllloooo---pytnwrd
4. update (类似集合的update,进行更新)
举例:
a.update("hello123121")
print(a)
# 结果:
Counter({'-': 3, '1': 3, '2': 2, '3': 1, 'd': 1, 'e': 3, 'h': 4, 'l': 7, 'n': 1, 'o': 5, 'p': 1, 'r': 1, 't': 1, 'w': 1, 'y': 1})
5. subtract (类似update,做减法)
s1 = "abcd"
s2 = "cdef"
a1 = Counter(s1)
a2 = Counter(s2)
a1.subtract(a2)
print(a1)
# 结果:
Counter({'a': 1, 'b': 1, 'c': 0, 'd': 0, 'e': -1, 'f': -1