一、collections模块
1、其他数据类型
在内置数据类型(str、dict、list、tuple、set)的基础上,collections模块还提供了了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict。
2、namedtuple(具名元组)
①、用具名元组表示一个点坐标
from collections import namedtuple
Point = namedtuple('Point',['x','y'])
p = Point(1, 2)
print(p)
# 输出
Point(x=1, y=2)
②、用具名元组记录一个城市的信息
from collections import namedtuple
City = namedtuple('City','name country population coordinates')
# 第一个是类名,第二个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串
tokyo = City('Tokyo','JP',36.933,(35.689722,139.691667))
print(tokyo)
# 输出
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
③、格式:namedtuple('名称',[属性list])
3、deque(双端队列)
①、使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈。
②、qeque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效的往头部添加或删除元素。
from collections import deque
q = deque(['a','b','c'])
q.pop()
q.append('x')
q.popleft()
q.appendleft('y')
print(q)
# 输出
deque(['y', 'b', 'x'])
③、deque还支持insert()方法,可以在任意位置插值
from collections import deque
q = deque(['a','b','c'])
q.insert(1,'x')
print(q)
# 输出
deque(['a', 'x', 'b', 'c'])
④、queue 队列
import queue
q = queue.Queue() # 创建一个队列对象
q.put(1) # 往队列里面放值
q.get() # 取出队列里面的值
q.get() # 队列中无值可取,程序会在原地等待
4、OrderedDict(有序列表)
使用dict时,key是无序的,在对dict做迭代时,我们无法确定key的顺序,如果要保持key的顺序,可以用OrderedDict
from collections import OrderedDict
d = dict([('a',1),('b',2),('c',3)])
print(d)
od = OrderedDict([('a',1),('b',2),('c',3)])
print(od)
# python2中结果
>>> d
{'a': 1, 'c': 3, 'b': 2}
>>> od
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# Python3中结果
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> od
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# python3对列表做了优化,使他看上去是有序的
5、defaultdict(默认值字典)
①、有如下值[11, 22, 33, 44, 55, 66, 77, 88, 99, 90],将所有大于66的值保存至字典的第一个key中,将小于66的值保存至第二个key的值中
# 原生字典解决方案
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = {}
for value in values:
if value>66:
if my_dict.__contains__('k1'):
my_dict['k1'].append(value)
else:
my_dict['k1'] = [value]
else:
if my_dict.__contains__('k2'):
my_dict['k2'].append(value)
else:
my_dict['k2'] = [value]
print(my_dict)
# 输出
{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}
# defaultdict解决方案
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list) # 该字典新增的键对应的值是一个空列表
for value in values:
if value>66:
my_dict['k1'].append(value)
else:
my_dict['k2'].append(value)
print(my_dict)
# 输出
defaultdict(, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})
②、使用dict时,如果引用的key不存在就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1'])
print(dd['key2'])
# 输出
abc
N/A
# key存在时返回key的值,key不存在时返回你设置的默认值
6、Counter(计数)
Counter类的目的是用来跟踪值出现的次数,他是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的integer(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
from collections import Counter
c = Counter('abcdeabcdabcaba')
print(c)
# 输出
Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
二、时间模块
1、表示时间的三种方式
①、时间戳(timestamp):表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。
②、格式化的时间字符串(format string):1999-12-06
③、元组(struct_time):struct_time元组中共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中的几天等)
2、import time 导入时间模块
3、time.time()返回时间戳,time.sleep(n)使程序暂停n秒
4、时间字符串
import time
print(time.strftime("%Y-%m-%d %X"))
print(time.strftime("%Y-%m-%d %H-%M-%S"))
# 输出
2019-07-18 22:12:55
2019-07-18 22-12-55
5、时间元组:localtime将一个时间戳转换为当前时区的struct_time
import time
print(time.localtime())
# 输出
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=18, tm_hour=22, tm_min=21, tm_sec=22, tm_wday=3, tm_yday=199, tm_isdst=0)
6、时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
7、几种格式之间的转换
8、datatime模块
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之间的关系
三、random模块
1、几种方法
print(random.randint(1,6))
#随机取一个你提供的整数范围内的数字,包含首尾
print(random.random())
# 随机取0-1之间的浮点数
print(random.choice([1, 2, 3, 4, 5, 6]))
# 摇号 随机从列表中取一个元素
res = [1, 2, 3, 4, 5, 6]
random.shuffle(res)
print(res)
# 洗牌
2、生成随机验证码
''''''
import random
'''
随机n位验证码
由大写字母,小写字母,数字组成,每种的个数不限
封装成一个函数,用户想生成几位就生成几位
'''
def get_code(n):
code = ''
for i in range(n):
# 生成随机的大写字母,小写字母,数字
upper_str = chr(random.randint(65, 90)) # (****)
lower_str = chr(random.randint(97, 122)) #(****)
random_int = str(random.randint(0, 9))
# 从上面三个中随机选择一个作为随机验证码的某一位
code += random.choice([upper_str,lower_str,random_int])
return code
res = get_code(4)
print(res)
四、os模块
1、os模块是和操作系统打交道的模块
import os
BASE_DIR = os.path.dirname(__file__)
MOVIE_DIR = os.path.join(BASE_DIR,'老师们的作品')
movie_list = os.listdir(MOVIE_DIR)
while True:
for i,j in enumerate(movie_list,1):
print(i,j)
choice = input('你想看谁的啊(今日热搜:tank老师)>>>:').strip()
if choice.isdigit(): # 判断用户输入的是否是纯数字
choice = int(choice) # 传成int类型
if choice in range(1,len(movie_list)+1): # 判断是否在列表元素个数范围内
# 获取用户想要看的文件名
target_file = movie_list[choice-1]
# 拼接文件绝对路径
target_path = os.path.join(MOVIE_DIR,target_file)
with open(target_path,'r',encoding='utf-8') as f:
print(f.read())
os.mkdir('tank老师精选') # 自动创建文件夹
print(os.path.exists(r'D:\Python项目\day16\rion老师精选')) # 判断文件是否存在
print(os.path.exists(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 判断文件是否存在
print(os.path.isfile(r'D:\Python项目\day16\tank老师精选')) # 只能判断文件 不能判断文件夹
print(os.path.isfile(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 只能判断文件 不能判断文件夹
os.rmdir(r'D:\Python项目\day16\老师们的作品') # 只能删空文件夹
print(os.getcwd())
print(os.chdir(r'D:\Python项目\day16\老师们的作品')) # 切换当前所在的目录
print(os.getcwd())
# 获取文件大小
print(os.path.getsize(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 字节大小
with open(r'D:\Python项目\day16\老师们的作品\tank老师.txt',encoding='utf-8') as f:
print(len(f.read()))
2、常用方法
os.path.dirname(__file__)
# 返回该文件所在文件夹的路径
os.listdir(path)
# 返回一个列表,列表中的元素就是path路径下所有的文件名
os.path.join(BASE_DIR,target_file)
# 拼接路径
os.path.exists()
# 判断文件是否存在
os.path.isfile()
# 只能判断文件
os.mkdir()
# 创建文件夹
os.rmdir()
# 删除空文件夹
os.getcwd()
# 获取当前所在路径
os.chdir()切换路径,类似于cd命令
os.path.getsize()
# 获取文件大小
os.remove()
# 删除文件
os.rename()
# 重命名
五、sys模块
import sys
# sys.path.append() # 将某个路径添加到系统的环境变量中
# print(sys.platform)
# print(sys.version) # python解释器的版本
print(sys.argv) # 命令行启动文件 可以做身份的验证
if len(sys.argv) <= 1:
print('请输入用户名和密码')
else:
username = sys.argv[1]
password = sys.argv[2]
if username == 'jason' and password == '123':
print('欢迎使用')
# 当前这个py文件逻辑代码
else:
print('用户不存在 无法执行当前文件')
sys.path
# 是一个列表,系统的环境变量,列表的第一个值就是执行文件所在的文件夹路径
sys.path.append()
# 往环境变量里添加路径
sys.argv()
# 是一个列表,列表中的每一个元素就是位于Python命令之后的一个个值
# 可以用于设置当前文件的权限
六、序列化模块
"""
序列化
序列:字符串
序列化:其他数据类型转换成字符串的过程
序列化的优点:
1.方便存储
2.网络传输
写入文件的数据必须是字符串
基于网络传输的数据必须是二进制
序列化:其他数据类型转成字符串的过程
反序列化:字符串转成其他数据类型
json模块(******)
所有的语言都支持json格式
支持的数据类型很少 字符串 列表 字典 整型 元组(转成列表) 布尔值
pickle模块(****)
只支持python
python所有的数据类型都支持
pickle序列化之后的结果是一个二进制数据(bytes类型),所以文件的打开模式必须是b模式
import json
"""
dumps:序列化 将其他数据类型转成json格式的字符串
loads:反序列化 将json格式的字符串转换成其他数据类型
dumps和loads只能接收1个参数:待序列化的字符串
json.dumps()指定ensure_ascii=False参数时可以使序列化后的中文字符正常显示
dump
load
dump可以接收两个参数,第一个是待序列化的字符串,第二个是文件对象,他可以将序列化后的字符串自动写入文件
"""
d = {"name":"jason"}
print(d)
res = json.dumps(d) # json格式的字符串 必须是双引号 >>>: '{"name": "jason"}'
print(res,type(res))
res1 = json.loads(res)
print(res1,type(res1))
d = {"name":"jason"}
with open('userinfo','w',encoding='utf-8') as f:
json.dump(d,f) # 装字符串并自动写入文件
with open('userinfo','r',encoding='utf-8') as f:
res = json.load(f)
print(res,type(res))
with open('userinfo','w',encoding='utf-8') as f:
json.dump(d,f) # 装字符串并自动写入文件
json.dump(d,f) # 装字符串并自动写入文件
with open('userinfo','r',encoding='utf-8') as f:
res1 = json.load(f) # 不能够多次反序列化
res2 = json.load(f)
print(res1,type(res1))
print(res2,type(res2))
with open('userinfo','w',encoding='utf-8') as f:
json_str = json.dumps(d)
json_str1 = json.dumps(d)
f.write('%s\n'%json_str)
f.write('%s\n'%json_str1)
with open('userinfo','r',encoding='utf-8') as f:
for line in f:
res = json.loads(line)
print(res,type(res))
t = (1,2,3,4)
print(json.dumps(t))
d1 = {'name':'朱志坚'}
print(json.dumps(d1,ensure_ascii=False))
pickle
import pickle
d = {'name':'jason'}
res = pickle.dumps(d) # 将对象直接转成二进制
print(pickle.dumps(d))
res1 = pickle.loads(res)
print(res1,type(res1))
"""
用pickle操作文件的时候 文件的打开模式必须是b模式
"""
with open('userinfo_1','wb') as f:
pickle.dump(d,f)
with open('userinfo_1','rb') as f:
res = pickle.load(f)
print(res,type(res))
七、subprocess模块
"""
1.用户通过网络连接上了你的这台电脑
2.用户输入相应的命令 基于网络发送给了你这台电脑上某个程序
3.获取用户命令 里面subprocess执行该用户命令
4.将执行结果再基于网络发送给用户
这样就实现 用户远程操作你这台电脑的操作
"""
while True:
cmd = input('cmd>>>:').strip()
import subprocess
obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# print(obj)
print('正确命令返回的结果stdout',obj.stdout.read().decode('gbk'))
print('错误命令返回的提示信息stderr',obj.stderr.read().decode('gbk'))
import subprocess
sub_obj = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(sub_obj.stdout.read()) # 直接拿到的是一个二进制数据(该二进制的编码是参考执行该命令计算机的操作系统默认编码)
print(sub_obj.stdout.read().decode('gbk')) # 直接拿到的是一个二进制数据(该二进制的编码是参考执行该命令计算机的操作系统默认编码) windows