7.18collection等模块

一、collections模块

在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

1.1namedtuple(具名元祖)

简单理解就是具有名字的元祖。生成:可以使用名字来访问元素内容的tuple元祖

应用场景1:定位坐标
from collections import namedtuple
point=namedtuple('坐标',['x','y','z'])
p=point(1,2,4)
print(p.y)

注意第二个参数:既要用可以传可迭代参数;也可以传字符串(字符串之间要用空格隔开)

第一个是类名,第二个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串

point = namedtuple('坐标','x y z')

注意传值要与namedtuple匹配

p=point(1,2,4)
应用场景2:在线打牌
# card=namedtuple('扑克牌','colour number')
#可以写可迭代对象:
card=namedtuple('扑克牌',['colour','number'])
a=card('♥','A')
print(a)
print(a.colour)
#扑克牌(colour='♥', number='A')
#♥

应用场景3:记录城市信息

city=namedtuple('日本','name person size')
a=city('东京','B老师','D')
print(a)
print(a.size)

应用场景4:表示一个圆

circle=namedtuple('圆',('x','y','r'))
a=circle(20,30,50)
print(a)

1.2deque(双端队列)

1.2.1普通队列(导入import queue模块)

队列:先进先出(FIFO first in first out)

队列的几个方法:

生成队列对象:q=queue.Queue()

给队列增加值:q.put()

从队列中取值:q.get()

import queue
q=queue.Queue()# 生成队列对象
q.put(1)# 往队列中添加值
q.put(2)
print(q.get())# 朝队列要值
print(q.get())

当队列中的值去完了,程序会原地等待,直到你往队列中增加值为止

1563439407641

1.2.2双端队列(导入from collection import deque)

双端队列的增加值与取值方式:

1.增加值:

append、appendleft

2.取值

pop、popleft

from collections import deque
q=deque(['a','b','c'])

#增加值
q.appendleft('g')
print(q)

#弹出值
q.popleft()
print(q)

另外:队列不应该支持任意为止插值,虽然可以插值。

插值的方法:

q.insert(索引号,插入的内容)

三、OrderedDict(有序字典)

原先字典是“无序”的。复习一个生成字典的方式:

(列表中套元祖)

d = dict([('a', 1), ('b', 2), ('c', 3)])
d # dict的Key是无序的

注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']

四、defaultdict(默认值字典)

defaultdict是Python内建dict类的一个子类,第一个参数为default_factory属性提供初始值,默认为None。它覆盖一个方法并添加一个可写实例变量。它的其他功能与dict相同,但会为一个不存在的键提供默认值,直接新建一个K即可。从而避免KeyError异常。

有如下值集合 [11,22,33,44,55,66,77,88,99,90],将所有大于66的值保存至字典的第一个key中,将小于66 的值保存至第二个key的值中。

4.1在字典中创建一个新的空列表,用来存在新增K对应的值

from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)  # 后续该字典中新建的key对应的value默认就是列表
print(my_dict['aaa'])
for value in values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)
print(my_dict)

4.2defaultdict()新建一个

my_dict1 = defaultdict(int)
my_dict1['H']=2
print(my_dict1)

五、Counter(以字典形式计数)

Counter类的目的是s用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。


from collections import Counter
s='dfeaerfdsfeafeasfawef'
print(Counter(s))

六、时间模块

三种表现形式
1.时间戳(timestamp)
2.格式化时间(用来展示给人看的):Format String:1999-12-1
3.结构化时间((struct_time):(年,月,日,时,分,秒,一年中第几周,一年中第几天等)

import time
print(time.strftime('%Y-%m-%d %X'))

%X等价于%H:%M:%S。

注意只有m和d是小写

print(time.strftime('%Y-%m-%d %H:%M:%S'))

打印几时几分

print(time.strftime('%H:%M'))

打印年月

print(time.strftime('%Y/%m'))

时间元组: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)

小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的

几种格式之间的转换

1563450518967

时间戳-->结构化时间
time.gmtime(时间戳)
UTC时间,与英国伦敦当地时间一致time.localtime(时间戳)
当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间

>>>time.gmtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
>>>time.localtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)

结构化时间-->时间戳 
time.mktime(结构化时间)

>>>time_tuple = time.localtime(1500000000)
>>>time.mktime(time_tuple)
1500000000.0

七、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对象

timedelta对象 = 日期对象 +/- 日期对象
current_time = datetime.date.today()  # 日期对象
timetel_t = datetime.timedelta(days=7)  # timedelta对象
res1 = current_time+timetel_t  # 日期对象

print(current_time - timetel_t)
print(res1-current_time)
小练习 计算今天距离今年过生日还有多少天
birth = datetime.datetime(2019,12,21,8,8,8)
current_time = datetime.datetime.today()
print(birth-current_time)

UTC时间
dt_today = datetime.datetime.today()
dt_now = datetime.datetime.now()
dt_utcnow = datetime.datetime.utcnow()
print(dt_utcnow,dt_now,dt_today)

八、random模块(随机模块)

import random

随机选取整数范围内的数字:randint

print(random.randint(1,6))

随机取0-1之间小数:random.random()

print(random.random())

随机从列表中取一个元素

import random
print(random.choice([1,2,3,4,5,6])) 

shuffle将整个列表顺序打乱

res = [1,2,3,4,5,6]
random.shuffle(res)  # 洗牌
print(res)
生成随机验证码(例题)
def outter(n):
    code=''
    for i in range(n):
        upper_str=chr(random.randint(65,90))
        low_str=chr(random.randint(97,122))
        my_int=str(random.randint(0,9))
        code += random.choice([upper_str,low_str,my_int])
    return code
res=outter(5)
print(res)

九、os模块和sys模块

os模块:跟操作系统打交道的模块
sys模块:跟python解释器打交道模块

os.listdir(r'路径')。会将当前文件夹下所有文件展示出来

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())

import sys

将某个路径添加到系统环境变量中

sys.path.append()

sys.argv

获取在后面输入的值

1563454089149

获取用户输入选择功能

import sys
print(sys.argv)  # 命令行启动文件 可以做身份的验证
if len(sys.argv) <= 1:
    print('请输入用户名和密码')
else:
    username = sys.argv[1]
    password = sys.argv[2]
    if username == 'wuxi' and password == '123':
        print('欢迎使用')
        # 当前这个py文件逻辑代码
    else:
        print('用户不存在 无法执行当前文件')

十、序列化模块

序列:字符串
序列化:其他数据类型转换成字符串的过程

写入文件的数据必须是字符串
基于网络传输的数据必须是二进制

序列化:其他数据类型转成字符串的过程
反序列化:字符串转成其他数据类型

json模块(******)
    所有的语言都支持json格式
    支持的数据类型很少  字符串 列表 字典 整型 元组(转成列表)  布尔值


pickle模块(****)
    只支持python
    python所有的数据类型都支持
1.import json

dumps和loads
  在内存中做数据转换:
    dumps  数据类型转成字符串  #序列化
    loads   字符串转成数据类型  #反序列化
dump和load
  直接将数据类型写入文件,直接从文件中读出数据类型
    dump  数据类型写入文件  #序列化
    load  从文件读出数据类型  #反序列化
2.pickle模块
  1.支持在python中几乎所有的数据类型
  2.dumps序列化的结果只能是字节
  3.只能在python中使用
  4.在和文件操作的时候,需要用rb,wb的模式打开文件
  5.可以多次dump和load

import json
d = {"name":"jason"}
res = json.dumps(d)  # json格式的字符串 必须是双引号
print(res,type(res))
#{"name": "jason"} <class 'str'>
res1 = json.loads(res)
print(res1,type(res1))

dump和load

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))

写入多次

import json
d={'name':'1'}
with open('userinfo','w',encoding='utf-8') as f:
    json.dump(d,f)  # 装字符串并自动写入文件
    json.dump(d,f)  # 装字符串并自动写入文件
#写入两次。结果是并排写{"name": "1"}{"name": "1"}

此时load不能讲其取出,会报错。因为是同一行,不能不知道从何处取

解决方法:用dumps序列化

with open('userinfo','w',encoding='utf-8') as f:
	str_d=json.dumps(d)
	f.write('%s
'%str_d)
	

读的步骤:用loads

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))

json中有中文:会出来二进制数

使用ensure_=ascill=False

d={'name':'侍玲玲'}
print(json.dumps(d))

十一、pickle模块

import pickle
d = {'name':'wuxi'}
res = pickle.dumps(d) 
print(res) # 将对象直接转成二进制
res1 = pickle.loads(res)# 将对象还原成字典
print(res1,type(res1))

用pickle操作文件的时候 文件的打开模式必须是b模式

import pickle
d={'name':'sll'}
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

sub :子
process:进程

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'))
原文地址:https://www.cnblogs.com/ZDQ1/p/11210365.html