常用模块一
collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple:生成可以使用名字来访问元素内容的tuple
2.deque:双端队列,可以快速的从另外一侧追加和推出对象
3.Counter:计数器,主要用来计数
4.OrderedDict:有序字典
5.defaultdict:带有默认值的字典
namedtuple(具名元组)
我们知道tuple可以表示不变元组,例如,一个点的二维坐标就可以表示成:
>>>p = (1,2)
但是,看到(1,2),很难看出这个tuple是用来表示一个坐标的。
这是,namedtuple就派上用场:
from collections import namedtuple
Point = namedtuple('point', ['x', 'y'])
# 相当于定义类
p = Point(1, 2)
# 相当于定义对象
print(p.x)
>>>1
print(p.y)
>>>2
用具名元组来记录一个城市的信息
City = namedtuple('City', 'country population coordinates')
# 第一个是类名,第二个是类的各个字段的名字后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串
beijin = City('china', 14.3, (35, 13))
print(beijin.country)
print(beijin.population)
print(beijin.coordinates)
deque
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储(每次插入和删除都要找到该元素的前趋后继的关系,进行了大量元素的移动),数据量大的时候,插入和删除效率就很低了。
ps:队列是先进先出的线性表,栈是先进后出的线性表
deque是为了高效的实现插入和删除操作的双向列表,适合用于队列和栈:
from collections import deque
lis = ['a', 'b', 'c']
q = deque(lis)
q.append('d')
q.appendleft('y')
print(q)
>>>deque(['y', 'a', 'b', 'c', 'd'])
print(lis)
>>>['a', 'b', 'c']
#原变量没有变
deque除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素。
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
print(d)
>>>{'a': 1, 'b': 2, 'c': 3}
#Key是无序的
od=OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print([i for i in od])
>>>['a', 'b', 'c']
#有序的
print(od['a'])
>>>1
#可以用key取值
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
odict_keys(['z', 'y', 'x'])
defaultdict
#例子:
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict=defaultdict(list)
#确定value为list类型
for v in values:
if v>66:
my_dict['k1'].append(v)
else:
my_dict['k2'].append(v)
counter
counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对应形式存储,其中元素作为key,其计数作为value。计数值可以使任意的interger。
c = Counter('abcdeabcdabcaba')
print c
输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
时间模块
和时间有关系的模块我们就要用到时间模块。
#常用方法
1.time.sleep(sec)
推迟指定的时间运行,单位为秒。
2.time.time()
获取当前的时间戳
表示时间的三种方式
在python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:
(1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
(2)格式化的时间字符串(Format String): ‘1999-12-06’(‘%H-%m-%d ’)
%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 当前时区的名称
%% %号本身
(3)元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
索引(Index) | 属性(Attribute) | 值(Values) |
---|---|---|
0 | tm_year(年) | 比如2011 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 60 |
6 | tm_wday(weekday) | 0 - 6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
导入模块,认识python中表示时间段的几种格式:
import time
# 时间戳:
print(time.time())
# 1599185296.0382762
# 时间字符串
print(time.strftime('%Y-%m-%d %X'))
'2020-09-04 10:10:27'
print(time.strftime('%Y-%m-%d %H-%M-%S'))
'2020-09-04 10-11-19'
# 时间元组:localtime将一个时间戳转换为当前时区的struct_time
print(time.localtime())
# time.struct_time(tm_year=2020,
# tm_mon=9, tm_mday=4, tm_hour=10,
# tm_min=12, tm_sec=38, tm_wday=4,
# tm_yday=248, tm_isdst=0)
小结:时间戳是计算机能够识别的时间;时间字符串是人能够看到的时间;元组则是用来操作时间
几种格式之间的转换
# 时间戳---->时间结构---->格式化的字符串
struct_time=time.gmtime(1) #指定时间戳---->时间结构
res=time.strftime('%Y-%m-%d %X',struct_time)
#1970-01-01 08:00:01 时间戳的起点
print(res)
# 格式化的字符串---->时间结构---->时间戳
struct_time=time.strptime('1970-01-01 08:00:01','%Y-%m-%d %X') #时间结构
print(struct_time)
res=time.mktime(struct_time) #时间结构---->时间戳
print(res)
ps:
>>>time.mktime(struct_time) #时间结构---->时间戳
>>>time.gmtime(timestamp) #时间戳---->时间结构
时间戳与格式化字符串的转换,并不是直接互相转换,都需要进行与结构时间的交互,
成为结构时间后才能转化成时间戳或是格式化字符串。
#结构化时间 --> %a %b %d %H:%M:%S %Y串
#time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串
print(time.asctime(time.localtime(3333.3))) #将时间戳转换成时间结构再传入
>>>Thu Jan 1 08:55:33 1970
#时间戳 --> %a %b %d %H:%M:%S %Y串
#time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串
print(time.ctime(3333.3)) #直接传入时间戳转换
>>>Thu Jan 1 08:55:33 1970
datetime模块
import datetime
# 自定义日期
res = datetime.date(2019, 7, 15)
print(res) # 2019-07-15
# 获取本地时间
# 年月日
now_date = datetime.date.today()
print(now_date) # 2019-07-01
# 年月日时分秒
now_time = datetime.datetime.today()
print(now_time) # 2019-07-01 17:46:08.214170
# 无论是年月日,还是年月日时分秒对象都可以调用以下方法获取针对性的数据
# 以datetime对象举例
print(now_time.year) # 获取年份2019
print(now_time.month) # 获取月份7
print(now_time.day) # 获取日1
print(now_time.weekday()) # 获取星期(weekday星期是0-6) 0表示周一
print(now_time.isoweekday()) # 获取星期(weekday星期是1-7) 1表示周一
# timedelta对象
# 可以对时间进行运算操作
import datetime
# 获得本地日期 年月日
tday = datetime.date.today()
# 定义操作时间 day=7 也就是可以对另一个时间对象加7天或者减少7点
tdelta = datetime.timedelta(days=7)
# 打印今天的日期
print('今天的日期:{}'.format(tday)) # 2019-07-01
# 打印七天后的日期
print('从今天向后推7天:{}'.format(tday + tdelta)) # 2019-07-08
# 总结:日期对象与timedelta之间的关系
"""
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
random模块
random模块可以产生一个随机数或者从序列中获取一个随机元素。它的常用方法和使用例子如下:
import random
# 随机小数
print(random.random()) # 大于0且小于1之间的小数
# 0.9735061401282169
print(random.uniform(1, 3)) # 大于1小于3的小数
# 2.1402347559918633
# 随机整数
print(random.randint(1, 5)) # 大于等于1且小于等于5之间的整数
print(random.randrange(1, 10, 2)) # 大于等于1且小于10之间等差为2的整数(奇数)
# 随机选择一个返回
print(random.choice([1, 'aaa', [4, 5]])) # 1,'aaa',[4,5]随机一个
print(random.sample([1, '23', [4, 5]], 2)) # 列表中任意两个(可以自己定)元素
# 打乱列表顺序
item = [1, 3, 5, 7, 9]
random.shuffle(item)
print(item)
# [5, 3, 7, 1, 9]
生成随机验证码
import random
def v_code():
code = ''
for i in range(5):
num=random.randint(0,9)
alf=chr(random.randint(65,90))
add=random.choice([num,alf])
code="".join([code,str(add)])
return code
print(v_code())
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的大小
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
sys模块
sys模块是与python解释器交互的一个接口
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1)
sys.version 获取Python解释程序的版本信息
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
序列化
什么叫序列化——将原来的字典、列表等内容转换成一个字符串的过程就叫做序列化。
序列化目的
1、以某种存储形式使自定义对象持久化。
2、将对象从一个地方传递到另一个地方。
3、使程序更具维护性
json
json模块提供了四个功能:dumps、dump、loads、load
import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的
dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
#ensure_ascii=False 可以存入中文
dic={'k1':'张三','k2':'李四'}
with open('dic.json',mode='wt',encoding='utf-8')as f:
json.dump(dic,f)
>>>{"k1": "\u5f20\u4e09", "k2": "\u674e\u56db"}
with open('dic.json',mode='wt',encoding='utf-8')as f:
json.dump(dic,f,ensure_ascii=False)
>>>{"k1": "张三", "k2": "李四"}
pickle
pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic) #一串二进制内容
dic2 = pickle.loads(str_dic)
print(dic2) #字典
import time
struct_time = time.localtime(1000000000)
print(struct_time)
f = open('pickle_file','wb')
pickle.dump(struct_time,f)
f.close()
f = open('pickle_file','rb')
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)
json & pickle 对比与总结
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换(只支持字符串、列表、字典三种数据类型)
- 优势:可以跨平台、跨语言交互
- 劣势:不能识别所有的python数据类型
- pickle,用于python特有的类型 和 python的数据类型间进行转换(python所有数据类型)
- 优势:可以识别所有的python数据类型(如:能识别python中的对象)
- 劣势:不能跨平台、跨语言交互
- dumps与loads只进行了数据类型的转换,不能执行存入硬盘的功能
- dump与load进行了数据类型的转换,也执行了存入硬盘中的功能