Python 常用模块

编程入门 行业动态 更新时间:2024-10-14 14:19:06

Python 常用<a href=https://www.elefans.com/category/jswz/34/1771428.html style=模块"/>

Python 常用模块

目录

      • 时间模块
        • 将 时间戳 转换成 时间元组
        • 将 时间元组 转换成 时间戳
        • 将 时间元组 转换成 字符串
        • 将 时间字符串 转换成 时间元组
        • 时间的统计作用
        • 练习题
      • random模块
        • random.choice()
        • random.sample()
        • random.randrange()
        • random.random()
        • random.uniform()
        • random.int()
        • random.shuffle()
        • 练习题
      • sys模块
        • sys.argv
        • sys.path
        • sys.modules
      • os模块
        • os模块相关
        • os.path
        • 练习题
      • collections模块
        • Counter(计数器)
        • defaultdict (默认值字典/不常用)
        • namedtuple
        • 栈(stack)
        • 队列(queue)
        • functools模块
        • wraps
        • reduce 归纳
        • 偏函数
      • 练习题

时间模块

UTC时间:格林威治时间,世界标准时间,世界协调时间 ---  UTC+8 (北京时间),东八区,
比世界标准时间快 8个小时
DST夏令时:是一种为了节约资源而人为规定的时间,一般夏天调早一小时

时间的三种表现形式:时间戳、元组(struct_time)、格式化的时间字符串

时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。
我们运行“type(time.time())”,返回的是float类型。

时间元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
年   tm_year  比如2019
月   tm_mon   1到12
日   tm_mday  1到31时   tm_hour  0到23
分   tm_min   0到59
秒   tm_sec   0到59一周中的第几天  tm_wday(weekday) 0到6  0表示周一
一年中的第几天  tm_yday(一年中的第几天) 1到366
是否是夏令时	 tm_isdst(是否是夏令时) 默认为0
格式化的时间字符串(Format String): ‘2019-12-06’
%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 当前时区的名称
%% %号本身
import time获取当前时间的时间戳 time.time()
# 是一个浮点数, 单位是 秒
time1 = time.time()
# print(time1)
将 时间戳 转换成 时间元组
将时间戳转转换成 时间元组 (time.struct_time,结构化时间)time.gmtime() # 是将时间戳转换成世界标准时间(UTC)
tupleTiem = time.gmtime() # gmtime 空参时,默认是将当前时间(时间戳)转换成时间元组,
tupleTiem = time.gmtime(time1) # 结果和上面一样
#print(tupleTiem)time.localtime # 是将时间戳转换成本地时间(UTC+8)
tupleTime = time.localtime() # 空参时,默认是将当前本地时间转换成时间元组
tupleTime = time.localtime(time1) # 结果也是一样的
#print(tupleTime)# 表示昨天的时间
yesDayTime = time.time() - 60*60*24
tupleTime = time.localtime(yesDayTime)
print(tupleTime)
将 时间元组 转换成 时间戳
tupleTime = time.localtime() # 需要时间元祖,所以要先获取到
# tuple_time=time.gmtime()#1970标准
# 时间元组可以分别把每一项取出来,只需print(tuple_time.tm_year)# mktime需要一个时间元组参数, 但是会自动的舍弃掉小数位
time2 = time.mktime(tupleTime) # 不能是空参
print(time2)
将 时间元组 转换成 字符串
tupleTime = time.localtime()# 参数1: 是时间需要展示的格式(format)
# 参数2: 要转换的时间元组
# 2018-01-05 11:12:23
strTime = time.strftime( "%Y-%m-%d %H:%M:%S",tupleTime)
# strTime = time.strftime( "%Y/%m/%d",tupleTime)
# strTime = time.strftime( "%x %X",tupleTime)# 中文的年月日--- 2018年1月5日
# 错误写法 strTime = time.strftime( "%Y年%m月%d日 %H时%M分%S秒",tupleTime)
strTime = time.strftime("%Y{y}-%m{m}-%d{d} %H{a}-%M{b}-%S{c}",tuple_time).format(y="年",
m="月",d="日",a="时",b="分",c="秒") # 加上{变量},变量名自定义
print(strTime)
将 时间字符串 转换成 时间元组
# 参数1:字符串形式的 时间  --- 2018-01-05 11:59:17
# 参数2:是时间字符串的格式, 该格式需要与字符串形式的时间对应
tupleTime = time.strptime("2018-01-05 11:59:17","%Y-%m-%d %H:%M:%S")# 中文转换
tupleTime = time.strptime("2018年01月05日","%Y{y}%m{m}%d{d}".format(y="年",m = "月",d="日"))
# 注意要对应要转换的字符串格式
print(tupleTime)

datetime模块

datetime.now() # 获取当前datetime
datetime.utcnow() # 获取当前格林威治时间
from datetime import datetime#获取当前本地时间
a=datetime.now()
print('当前日期:',a)#获取当前世界时间
b=datetime.utcnow()
print('世界时间:',b)
datetime(2017, 5, 23, 12, 20) # 用指定日期时间创建datetime
from datetime import datetime#用指定日期创建
c=datetime(2017, 5, 23, 12, 20)
print('指定日期:',c)
>>>将以下字符串转换成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)
# 时间字符串格式化
>>>将以下datetime类型转换成字符串:
2017年9月28日星期4,10时3分43秒
Saturday, September 30, 2017
9/30/2017 9:22:17 AM
September 30, 2017from datetime import datetimei=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'))# 时间字符串格式化
>>>用系统时间输出以下字符串:
今天是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天'))
时间的统计作用
import time# time.sleep()
for i in  range(1,101):# 让程序睡一会, 单位: 秒# 会阻塞程序的运行time.sleep(1)print(i)# 统计程序运行的时间
startTime = time.time()
count = 0
for i in  range(1,100001):count += i # 运行一个程序
endTime = time.time()
runTime = endTime - startTime
print(runTime)# time.clock统计运行时间, 第一次调用clock的时间接近0, 后面再调用clock时,
# -是表示的是与第一次的时间差
startTime = time.clock()
print(startTime)
time.sleep(2)
endTime = time.clock()
print(endTime)
time.sleep(3)
endTime = time.clock()
print(endTime)
练习题
>>>查看一下2000000000时间戳时间表示的年月日
# 时间戳 - 结构化 - 格式化
struct_t = time.localtime(2000000000)
print(struct_t)
print(time.strftime('%y-%m-%d',struct_t))>>>将2008-8-8转换成时间戳时间
t = time.strptime('2008-8-8','%Y-%m-%d')
print(time.mktime(t))>>>请将当前时间的当前月1号的时间戳时间取出来 - 函数
# 2019-8-1
def get_time():st = time.localtime()st2 = time.strptime('%s-%s-1'%(st.tm_year,st.tm_mon),'%Y-%m-%d') # 里面先得到一个字符串return time.mktime(st2)
print(get_time())>>>计算时间差 2018-8-19 22:10:8 2018-8-20 11:07:3经过了多少时分秒str_time1 = '2018-8-19 22:10:8'
str_time2 = '2018-8-20 11:07:3'
struct_t1 = time.strptime(str_time1,'%Y-%m-%d %H:%M:%S')
struct_t2 = time.strptime(str_time2,'%Y-%m-%d %H:%M:%S')
timestamp1 = time.mktime(struct_t1)
timestamp2 = time.mktime(struct_t2)
sub_time = timestamp2 - timestamp1
gm_time = time.gmtime(sub_time)
# 1970-1-1 00:00:00
print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(gm_time.tm_year-1970,gm_time.tm_mon-1,gm_time.tm_mday-1,gm_time.tm_hour,gm_time.tm_min,gm_time.tm_sec))

random模块

random.choice()
numbers=[1,2,3,4,5,6,7]
res_num=random.choice(numbers) #选择随机数
print(res_num)# 也可以用于字符串
name=["张三","李四","王五","宝宝"]
res_name=random.choice(name) # choice 表示从多个数据中选择一个
print(res_name)# range 表示生成一定范围的多个整数,默认是从0开始,包前不包后
# range 可以设置两个参数,第一个参数表示起始值,第二个表示结束值(不包含)
# 1-100 (0-99),1-101 (1-100)
res_num=random.choice(range(1,101))
print(res_num)  #输出结果是从1-100中随机取出一个数
random.sample()
range.sample() 同时取出两个不重复的值
li = ['a','b',(1,2),123]
# print(random.choice(li))
print(random.sample(li,2))
random.randrange()
# 如果randrange里只有一个参数,表示 0-参数值(不包含)之间的随机数;
# 第一个参数 start 表示:随机数范围的起始值(包含),可以不写,默然是0
# 第二个参数 stop 表示:随机数范围的结束值(不包含)
# 第三个参数 step 表示:间隔几个数值,默认是1res=random.randrange(0,101,2) # 随机取出0-100间的一个偶数
print(res)  res=random.randrange(1,100,2) # 随机取出1-99 间的一个奇数
print(res)
random.random()
# 随机生成一个实数(小数)
res1=random.random() # 这里表示生成0-1(不包含)的实数,不需要填参数
print(res1)res1=random.random() *100+1 # 通过 运算来改变它的取值范围
print(res1)
random.uniform()
random.uniform() 取一个范围内的小数
# 随机生成一个实数(小数) 方法2
res2=random.uniform(1,2) # 必须要有参数,它是包前又包后
print(res2)
random.int()
random.int() 取随机整数
# 包前也包后
# 取随机整数 : 彩票 抽奖
print(random.randint(1,2)) # [1,2]# 区别
# print(random.randrange(1,2)) # [1,2)
random.shuffle()
# 将序列中的元素随机排列(操作的是原序列)
# 打乱一个列表的顺序,在原列表的基础上直接进行修改,节省空间
name=["张三","李四","王五","宝宝"]
random.shuffle(name)
print(name)
练习题
>>>验证码练习:
# 4位数字验证码
s = ''
for i in range(4):num = random.randint(0,9)s += str(num)
print(s)>>>6位数字验证码
s = ''
for i in range(6):num = random.randint(0,9)s += str(num)
print(s)# 函数版本
def code(n=6):s = ''for i in range(n):num = random.randint(0,9)s += str(num)return sprint(code(4))
print(code())>>>6位数字+字母验证码
# 一个位置上 出现的是数字还是字母应该是随机事件# 随机字母如何生成
s = ''
for i in range(6):# 生成随机的大写字母,小写字母,数字各一个num = str(random.randint(0,9))alpha_upper = chr(random.randint(65,90))alpha_lower = chr(random.randint(97,122))res = random.choice([num,alpha_upper,alpha_lower])s += res
print(s)# 函数版本
def code(n = 6):s = ''for i in range(n):# 生成随机的大写字母,小写字母,数字各一个num = str(random.randint(0,9))alpha_upper = chr(random.randint(65,90))alpha_lower = chr(random.randint(97,122))res = random.choice([num,alpha_upper,alpha_lower])s += resreturn s
print(code(4))
print(code())>>>进阶:所有功能都可以选择实现
4位数字验证码
6位数字验证码
6位数字+字母验证码def code(n = 6,alpha = True):s = ''for i in range(n):num = str(random.randint(0,9))if alpha:alpha_upper = chr(random.randint(65,90))alpha_lower = chr(random.randint(97,122))num = random.choice([num,alpha_upper,alpha_lower])s += numreturn s
print(code(4,False))
print(code(alpha=False))
>>>发红包,金额200元,发10个def red_packet(money,num):money = money * 100 # 转换成分ret = random.sample(range(1,money),num-1)# 这里为什么是num-1,我只要取出9个随机的数,前面插入0,ret.sort() # 总元素9个ret.insert(0,0) # 在列表头部插入0 #总元素10个ret.append(money) # 将总金额,添加到末尾,总元素11个for i in range(len(ret)-1): # 这里有11个元素了,所以要减一yield (ret[i+1] - ret[i])/100ret_g = red_packet(200,10)
for money in ret_g:print(money,end=" ")# 概率不公平方法:
def hongbao(sum,n):lst = []for i in range(n-1):number=random.uniform(0,sum)number=round(number,2)  # 保留两位小数sum=sum-numberlst.append(number)lst.append(sum)random.shuffle(lst)return lst
res=hongbao(100,3)
print(res)# 概率基本公平解法;
import random
def red_envelopes(money, numbers=10):name_list = ['梁慧', '蒲雪', '刘宁谦', '侯明魏', '尚红运','刘晓蕾', '杨文状', '姚尚', '冯俊才', '宋华生']sum_n = 0balance = moneyfor index, name in enumerate(name_list):random_money = random.uniform(0, balance / 3)if index == numbers - 1:print('%s grabbed %.2f element'% (name, money - sum_n))else:balance -= random_moneysum_n += random_moneyprint('%s grabbed %.2f element'% (name, random_money))money = int(input('请输入你要发红包的金额:'))
red_envelopes(money)# 概率做法:
import random
def Bonus(person,money):  # 5,200dict_person_money = {}for i in range(person):num = random.randint(1,100)  # 99 99 99 99 99dict_person_money["Person%s"%(i+1)] = num  # person1:99num_sum = 0for i in dict_person_money:num_sum += dict_person_money[i]  # 5 * 99 = 495for i in dict_person_money:    # 99/495 1/5 * 200 = 40x =round(dict_person_money[i]/num_sum*money,2)dict_person_money[i] = '$%s'%xreturn dict_person_moneyresult = Bonus(10,1)
print(result)

sys模块

sys 是和Python解释器打交道的:
sys.argv:命令行参数List,第一个元素是程序本身路径
sys.exit(n) :退出程序,正常退出时exit(0),错误退出sys.exit(1)
sys.version:获取Python解释程序的版本信息
sys.path:返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform:返回操作系统平台名称
sys.stdin          输入相关
sys.stdout         输出相关
sys.stderror       错误相关
import sys
try:sys.exit(1)
except SystemExit as e:print(e)
# 打印一个 进度 百分比
import sys
import timedef view_bar(num, total):rate = float(num) / float(total)rate_num = int(rate * 100)r = '\r%d%%' % (rate_num, )sys.stdout.write(r)sys.stdout.flush()if __name__ == '__main__':for i in range(0, 100):time.sleep(0.1)view_bar(i, 100)
sys.argv
sys.argvprint(sys.argv)  # argv的第一个参数 是python这个命令后面的值
usr = input('username')
pwd = input('password')
usr = sys.argv[1]
pwd = sys.argv[2]
if usr == 'alex' and pwd == 'alex3714':print('登录成功')
else:exit()# 1. 程序员 运维人员  在命令行运行代码
# 2. 操作系统input事件 阻塞 退出了CPU的竞争
sys.path
print(sys.path)
# 模块是存在解释器里的么??? 不是
模块应该是存在硬盘上
但是我在使用的时候 import --> 这个模块才到内存中一个模块能否被顺利的导入 全看sys.path下面有没有这个模块所在的绝对路径
自定义模块的时候 导入模块的时候 还需要再关注 sys.path
sys.path 模块搜索路径 是一个列表,这个列表中存的都是文件夹的绝对路径一个模块能被导入,是因为这个模块所在的文件夹在sys.path的列表中内置模块和第三方模块安装之后,不需要操作sys.path,直接用就行了如果一个模块导入不进来,那把这个模块的文件夹添加到sys.path中就行了
sys.modules
import reprint(sys.modules)  # 是我们导入到内存中的所有模块的名字 : 这个模块的内存地址
# 只要我们导入了,都能找到,是以字典形式保存的
print(sys.modules['re'].findall('\d','abc126'))
# print(re)
# print(re.findall('\d','abc126'))

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.stat('path/filename')  获取文件/目录信息 的结构说明stat 结构:st_mode: inode 保护模式st_ino: inode 节点号。st_dev: inode 驻留的设备。st_nlink: inode 的链接数。st_uid: 所有者的用户ID。st_gid: 所有者的组ID。st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。st_atime: 上次访问的时间。st_mtime: 最后一次修改的时间。st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
os.system("bash command") 运行shell命令,直接显示,执行操作系统的命令,没有返回值,适合实际的操作/删除一个文件 创建一个文件夹 类似于.exec
os.popen("bash command).read() # 运行shell命令,获取执行结果
# exec/eval执行的是字符串数据类型的 python代码;os.system 和 os.popen是执行字符串数据类型的 命令行代码
ret = os.popen('dir) # 适合做查看类的操作
s =ret.read()
print(s)
print(s.split('\n')) >>> 获取到 IP 地址
import os
import reres = os.popen("ipconfig")
s = res.read(1024)
ret=re.search("IPv4.*",s).group() # IPv4 地址 . . . . . . . . . . . . : 192.168.0.2
rt=re.split("IPv4.*?:",ret)[-1] # 192.168.0.2
print(rt)
os.getcwd() # 获取当前工作目录,即当前python脚本工作的目录路径,
# 并不是指当前文件所在的目录
# 是指当前文件是在哪个目录下执行的
print('-->',os.getcwd())
ret = os.popen('dir') # 查看
s =ret.read()
print(s) # 在不同的位置下运行,打印的结果也会随着变化
os.chdir("dirname") # 改变当前脚本工作目录;相当于shell下cd
os.chdir('D:\sylar\s15\day18')
ret = os.popen('dir') # 查看
s =ret.read()
print(s)ret = os.listdir('D:\sylar\s15')
print(ret)
os.chdir('D:\sylar\s15')
print(os.popen('dir').read())
os模块所做的事情定制了很多方法 间接的帮助你去调用操作系统的命令 获得结果然后帮助你分析整理成我们需要的数据类型的形态
也可以os.popen/os.system直接取调用操作系统的命令 获得结果但是 分析和整理的工作需要你自己做
用os模块的方法本身能够完成的功能我们就用定制好的方法就够了
如果有一天 你发现os模块定制好的功能解决不了我们的问题了而刚好操作系统的命令能够很好地帮助我们解决问题这个时候就用os.popen/os.system
os.path
os.path.abspath(path) # 返回path规范化的绝对路径os.path.split(path) # 将path分割成目录和文件名二元组返回
#就是把一个路径分成两段,第二段是一个文件/文件夹
path= os.path.split('D:/sylar/s15/day19/4.os模块.py')
print(path)
path= os.path.split('D:/sylar/s15/day19')
print(path) #('D:/sylar/s15', 'day19')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。否则返回Falseos.path.join(path1[, path2[, ...]]) # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略os.path.getatime(path) # 返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) # 返回path所指向的文件或者目录的最后修改时间os.path.getsize(path) # 返回path的大小
size= os.path.getsize(r'D:\sylar\s15\day19\4.os模块.py')  # 查看文件大小
print(size)ret1 = os.path.getsize('D:\sylar\s15\day19')
ret2 = os.path.getsize('D:\sylar\s15\day18')
ret3 = os.path.getsize('D:\sylar\s15\day17')
ret4 = os.path.getsize('D:\sylar\s15')
print(ret1,ret2,ret3,ret4)
# 所有的文件夹 都至少是4096个字节、8192
# Linux\mac 64字节 + 32字节/新文件
练习题
>>>
使用python代码统计一个文件夹中所有文件的总大小
你需要统计文件夹大小
D:\sylar\Pystudy\ 文件夹的大小拿到这个文件夹下所有的文件夹 和 文件是文件就取大小是文件夹 再打开这个文件夹 : 文件/文件夹# 递归做法:
def get_size(path):sum_size=0list_name=os.listdir(path)for name in list_name:abs_path=os.path.join(path,name)if os.path.isdir(abs_path):size=get_size(abs_path)sum_size+=sizeelse:sum_size+=os.path.getsize(abs_path)return sum_size# 注意返回值位置,它只会返回给上一层函数的调用者
print(get_size(r"F:\PyStudy"))# 堆栈循环解决
lst=[r"F:\PyStudy",]
sum_size=0
while lst: # 循环完一个列表的内容path=lst.pop() # 从右边取出列表中的一个元素list_name=os.listdir(path)for name in list_name:abs_path=os.path.join(path,name)if os.path.isdir(abs_path):lst.append(abs_path)else:sum_size+=os.path.getsize(abs_path)
print(sum_size)

collections模块

Counter(计数器)

Counter目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。
计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

Counter类创建的四种方法:# Counter类的创建 
>>> c = Counter()  # 创建一个空的Counter类
>>> c = Counter('gallahad')  # 从一个可iterable对象(list、tuple、dict、字符串等)创建
>>> c = Counter({'a': 4, 'b': 2})  # 从一个字典对象创建
>>> c = Counter(a=4, b=2)  # 从一组键值对创建
计数值的访问与缺失的键:
# 当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。# 计数值的访问
>>> c = Counter("abcdefgab")
>>> c["a"]
2
>>> c["c"]
1
>>> c["h"]
0
计数器的更新(update和subtract):
# 可以使用一个iterable对象或者另一个Counter对象来更新键值。# 计数器的更新包括增加和减少两种。其中,增加使用update()方法:# 计数器的更新(update)
>>> c = Counter('which')
>>> c.update('witch')  # 使用另一个iterable对象更新
>>> c['h']
3
>>> d = Counter('watch')
>>> c.update(d)  # 使用另一个Counter对象更新
>>> c['h']
4
减少则使用subtract()方法:# 计数器的更新(subtract)
>>> c = Counter('which')
>>> c.subtract('witch')  # 使用另一个iterable对象更新
>>> c['h']
1
>>> d = Counter('watch')
>>> c.subtract(d)  # 使用另一个Counter对象更新
>>> c['a']
-1
键的修改和删除:
# 当计数值为0时,并不意味着元素被删除,删除元素应当使用del。 键的删除
>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> c["b"] = 0
>>> c
Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
>>> del c["a"]
>>> c
Counter({'c': 2, 'b': 2, 'd': 1})
elements()
# 返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。元素排列无确定顺序,个数小于1的元素不被包含。# elements()方法 
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])
# 返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,排列是无确定顺序的。# most_common()方法>>> c = Counter('abracadabra')
>>> c.most_common()
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
>>> c.most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
浅拷贝copy:
>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> d = c.copy()
>>> d
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
算术和集合操作:
+、-、&、|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。
需要注意的是,得到的Counter对象将删除小于1的元素。# Counter对象的算术和集合操作
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d  # c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d  # subtract(只保留正数计数的元素)
Counter({'a': 2})
>>> c & d  # 交集:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d  # 并集:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})
其他常用操作:
# 下面是一些Counter类的常用操作,来源于Python官方文档# Counter类常用操作
sum(c.values())  # 所有计数的总数
c.clear()  # 重置Counter对象,注意不是删除
list(c)  # 将c中的键转为列表
set(c)  # 将c中的键转为set
dict(c)  # 将c中的键值对转为字典
c.items()  # 转为(elem, cnt)格式的列表
Counter(dict(list_of_pairs))  # 从(elem, cnt)格式的列表转换为Counter类对象
c.most_common()[:-n:-1]  # 取出计数最少的n个元素
c += Counter()  # 移除0和负值
from collections import Counterprint(Counter('我的天啊,居然中中了大奖哦')) # 迭代 计数li=["jay",'jay',"jay",'jj']
print(Counter(li)) # Counter({'jay': 3, 'jj': 1})c=Counter(li)
print(c.get('jay')) # 统计单个
print(Counter(li).get("jay"))dic={"a":"jay","b":"nb","d":"jj",'e':'jay'}
print(Counter(dic.values()))
defaultdict (默认值字典/不常用)

namedtuple

生成可以使用名字来访问元素内容的tuple

tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:p=(1,2)
但是,看到(1,2),很难看出这个tuple是用来表示坐标的。
那么,我们的namedtuple就能用上了。 
namedtuple('名称',‘属性list’)from  collections import namedtuple
point = namedtuple('point',['x','y'])
p = point(1,2)
print(p.x,p.y)、<br><br><br>
Circle = namedtuple('Circle', ['x', 'y', 'r']) # 用坐标和半径表示一个圆

命名元组(具名元组)详解:
内容摘自:

'''
namedtuple是一个 工厂函数,定义在python标准库的collections模块中,使用此函数可以创建一个可读性更强的元组
namedtuple函数所创建(返回)的是一个 元组的子类(python中基本数据类型都是类,且可以在buildins模块中找到)
namedtuple函数所创建元组,中文名称为 具名元组(命名元组)在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
使用命名元组,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问值得注意的是,具名元组和普通元组所需要的内存空间相同,
所以 不必使用性能来权衡是否使用命名元组
'''

namedtuple是一个函数,我们先来看下他的参数

def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):
# 有两个必填参数typename和field_names# typename# 参数类型为字符串
# 具名元组返回一个元组子对象,我们要为这个对象命名,传入typename参数即可# field_names# 参数类型为字符串序列
# 用于为创建的元组的每个元素命名,可以传入像['a', 'b']这样的序列,也可以传入'a b'或'a, b'这种被逗号或空格分割的单字符串
# 必须是合法的标识符。不能是关键字如class,def等# rename
# 注意的参数中使用了*,其后的所有参数必须指定关键字
# 参数为布尔值
# 默认为False。当我们指定为True时,如果定义field_names参数时,出现非法参数时,
# --会将其替换为位置名称。
#--如['abc', 'def', 'ghi', 'abc']会被替换为['abc', '_1', 'ghi', '_3']# defaults# 参数为None或者可迭代对象
# 当此参数为None时,创建具名元组的实例时,必须要根据field_names传递指定数量的参数
# 当设置defaults时,我们就为具名元组的元素赋予了默认值,
#--被赋予默认值的元素在实例化的时候可以不传入
# 当defaults传入的序列长度和field_names不一致时,函数默认会右侧优先
# 如果field_names是['x', 'y', 'z'],defaults是(1, 2),那么x是实例化必填参数,y默认为1,z默认为2

使用

# 理解了namedtuple函数的参数,我们就可以创建具名元组了
>>> Point = namedtuple('Point', ['x', 'y'])  # 返回一个名为`Point`的类,并赋值给名为`Point`的变量
>>> p = Point(11, y=22)     # 可以根据参数的位置,或具名参数来实例化(像普通的类一样)
>>> p[0] + p[1]             # 具名元组可以像普通元组一样通过`index`访问
33
>>> x, y = p                # 具名元组可以像普通元组一样解包
>>> x, y
(11, 22)
>>> p.x + p.y               # 具名元组还可以通过属性名称访问元组内容
33
>>> p                       # 具名元组在调用`__repr__`,打印实例时,更具可读性
Point(x=11, y=22)# 具名元组在存储csv或者sqlite3返回数据的时候特别有用
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):print(emp.name, emp.title)import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):print(emp.name, emp.title)

特性:具名元组除了拥有继承自基本元组的所有方法之外,还提供了额外的三个方法和两个属性,为了防止命名冲突,这些方法都会以下划线开头

使用技巧

纸牌游戏

import collections
# 将纸牌定义为具名元组,每个纸牌都有等级和花色
Card = collections.namedtuple('Card', 'rank suit')class FrenchDeck:# 等级2-Aranks = [str(n) for n in range(2,11)] + list('JQKA')# 花色红黑方草suits = 'spades diamonds clubs hearts'.split()# 构建纸牌def __init__(self):self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]# 获取纸牌def __getitem__(self, position):return self._cards[position]>>> french_deck = FrenchDeck()
>>> french_deck[0]
Card(rank='2', suit='spades')
>>> french_deck[0].rank
'2'
>>> french_deck[0].suit
'spades'
栈(stack)
# 模拟一个栈
# 自定错误
class StackFullException(Exception):passclass StackEmptyException(Exception):passclass Stack(object):def __init__(self,size):self.size=sizeself.Stack_list=[]self.top=0def push(self,el):if self.top>=self.size:raise StackFullException('your stack is full!!!')self.Stack_list.insert(self.top,el)self.top+=1def pop(self):if self.top==0:raise StackEmptyException('your stack is empty')self.top-=1el=self.Stack_list[self.top]return els=Stack(5)
s.push("你好啊")
s.push("你好帅")
s.push("才怪")
s.push("不照照镜子")
s.push("看看自己")
# s.push('没问题') # 超过最大容量print(s.pop())
print(s.pop())
print(s.pop())
print(s.pop())
print(s.pop())
print(s.pop()) # 取出时,超过

栈顶指针:指向下一个存放数据的位置(出栈 和 压栈)

队列(queue)
import queueq=queue.Queue()
q.put("min1")
q.put("min2")
q.put("min3")
print(q.get())
print(q.get())
print(q.get())

双向队列:

 from collections import deque

functools模块
wraps
from functools import wraps # 可以改变一个函数的名字from functools import wraps
def wrapper(fn):@wraps(fn) # 把inner改回原来需要被装饰函数的名字def inner(*args,**kwargs):print("aback")ret=fn(*args,**kwargs)return retreturn inner@wrapper
def func():print("想要被装饰")
print(func.__name__) # 没被@wrap装饰前是inner,装饰后变成想要改的名字
reduce 归纳
map映射:将参数二的值,一一作用到参数一,参数二必须是可迭代对象
print(list(map(lambda x:x**2,[i for i in range(10)])))
# 结果:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

运行结果:累加1-100,5050
reduce 会有一个初始默认值,不写为0
偏函数

练习题

>>>写一个copy函数,接受两个参数,第一个参数是源文件的位置,第二个参数是目标位置,
>将源文件copy到目标位置
import osdef copy_file(source_path, target_path):file_name = os.path.basename(source_path)if os.path.isfile(source_path) and os.path.isdir(target_path):target_path = os.path.join(target_path, file_name)if os.path.exists(target_path):print("已有同名文件")with open(source_path, 'rb') as f1, open(target_path, 'wb') as f2:# 如果with 不想写在同一行,中间写成 ,\while True:content = f1.read(1024)if len(content) == 0:breakf2.write(content)f2.flush()copy_file(r"F:\PyStudy\day17\code\test_home_work.py", r"F:\PyStudy\day17\test_copy")# 返回上层目录
def change_catlog(source_path,target_path):n=source_path.count("\\")-target_path.count("\\")#print(n)for i in range(n):path = os.path.dirname(source_path)path=os.path.dirname(path)print(path)
change_catlog(r"F:\PyStudy\day17\code\test_home_work.py",r"F:\PyStudy\day17")
>>>写一个函数,接受一个参数,如果是文件,就执行这个文件;
>如果是文件夹,就执行这个文件夹下所有的py文件import osdef exe_file(path):# 先判断这个path是文件还是文件夹,isdir isfile# 如果是文件,.py结尾的if os.path.isfile(path) and path.endswith('.py'):# 执行这个文件 :os.system('python %s' % (path))  # 模拟了在cmd中执行代码的过程# 如果是文件夹elif os.path.isdir(path):# 查看这个文件夹下的所有内容listdirfor name in os.listdir(path):abs_path = os.path.join(path, name)# 如果是文件.py结尾的if abs_path.endswith('.py'):# 执行这个文件:os.system('python %s'%abs_path)# print("abs_path:", abs_path)os.system('python %s' % (abs_path))# exe_file(r"F:\PyStudy\day17")
# exe_file(r"F:\PyStudy\day17\code\test5.py")

更多推荐

Python 常用模块

本文发布于:2024-02-12 12:15:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1687755.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模块   常用   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!