collections模块、time模块、datetime模块、random模块
今日学习内容总结
在昨日的学习中,我们了解了正则表达式的使用方法,并且对re模块进行了学习。因为python想要使用正则表达式,就需要借助于re模块。而今天我们对其他模块也来进行学习与使用。
re模块的补充说明
针对昨日已经学习的re模块常用方法,来做一个补充。
findall默认是分组优先展示,正则表达式中如果有括号分组,那么在展示匹配结果的时候,默认只演示括号内正则表达式匹配到的内容,同时也可以取消分组有限展示的机制。案例:
import re
ret = re.findall('a(b)c', 'abcabcabcabc')
print(ret) # ['b', 'b', 'b', 'b']
ret = re.findall('a(?:b)c', 'abcabcabcabc')
print(ret) # ['abc', 'abc', 'abc', 'abc']
ret = re.findall('(a)(b)(c)', 'abcabcabcabc')
print(ret) # [('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c')]
ret = re.findall('(?P<aaa>a)(b)(c)', 'abcabcabcabc')
print(ret) # [('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c')]
print(ret.group('aaa')) # 'list' object has no attribute 'group'
ret = re.search('a(b)c', 'abcabcabcabc')
print(ret.group()) # abc
print(ret.group(0)) # abc
print(ret.group(1)) # b 可以通过索引的方式单独获取分组内匹配到的数据
ret = re.search('a(b)(c)', 'abcabcabcabc')
print(ret.group()) # abc
print(ret.group(0)) # abc
print(ret.group(1)) # b 可以通过索引的方式单独获取分组内匹配到的数据
print(ret.group(2)) # c
# 分组之后还可以给组起别名
ret = re.search('a(?P<name1>b)(?P<name2>c)', 'abcabcabcabc')
print(ret.group('name1')) # b
print(ret.group('name2')) # c
collections模块
collections是日常工作中的重点、高频模块,常用类型有:1.计数器(Counter)。2.双向队列(deque)。3.默认字典(defaultdict)。4.有序字典(OrderedDict)。5.可命名元组(namedtuple)。
1.计数器(Counter)
Counter作为字典dicit()的一个子类用来进行hashtable计数,将元素进行数量统计,计数后返回一个字典,键值为元素,值为元素个数。
常用方法:
| 方法名 | 方法描述 |
|---|---|
| most_common(int) | 按照元素出现的次数进行从高到低的排序,返回前int个元素的字典 |
| elements | 返回经过计算器Counter后的元素,返回的是一个迭代器 |
| update | 和set集合的update一样,对集合进行并集更新 |
| substract | 和update类似,只是update是做加法,substract做减法,从另一个集合中减去本集合的元素 |
| iteritems | 返回由Counter生成的字典的所有item |
| iterkeys | 返回由Counter生成的字典的所有key |
| itervalues | 返回由Counter生成的字典的所有value |
代码案例:
from collections import Counter
str = "abcbcaccbbad"
li = ['a', 'b', 'c', 'a', 'b', 'b']
d = {'1': 3, '3': 2, '17': 2}
# Counter获取各元素的个数,返回字典
print(Counter(str)) # Counter({'b': 4, 'c': 4, 'a': 3, 'd': 1})
print(Counter(li)) # Counter({'b': 3, 'a': 2, 'c': 1})
print( Counter(d)) # Counter({'1': 3, '3': 2, '17': 2})
# most_common(int)按照元素出现的次数进行从高到低的排序,返回前int个元素的字典
d1 = Counter(str)
print(d1.most_common(2)) # [('b', 4), ('c', 4)]
# elements返回经过计算器Counter后的元素,返回的是一个迭代器
print(sorted(d1.elements())) # ['a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'd']
print( "".join(d1.elements())) # aaabbbbccccd
# 若是字典的话返回value个key
d2 = Counter(d)
print(sorted(d2.elements())) # ['1', '1', '1', '17', '17', '3', '3']
2.双向队列(deque)
队列:先进先出。默认是只有一端只能进另外一端只能出。双端队列:两端都可以进出
常用方法:
| 方法名 | 方法描述 |
|---|---|
| append | 队列右边添加元素 |
| appendleft | 队列左边添加元素 |
| clear | 清空队列中的所有元素 |
| count | 返回队列中包含value的个数 |
| extend | 队列右边扩展,可以是列表、元组或字典,如果是字典则将字典的key加入到deque |
| extendleft | 同extend,在左边扩展 |
| pop | 移除并返回队列右边的元素 |
| popleft | 移除并返回队列左边的元素 |
| remove(value) | 移除队列第一个出现的元素 |
| reverse | 队列的所有元素进行反转 |
| rotate(n) | 对队列数进行移动 |
代码案例:
from collections import deque
q = deque([1, 2, 3])
print(q) # deque([1, 2, 3])
q.append(444) # 右边添加元素
print(q) # deque([1, 2, 3, 444])
q.appendleft(666) # 左边添加元素
print(q) # deque([666, 1, 2, 3, 444])
q.pop() # 右边弹出元素
print(q) # deque([666, 1, 2, 3])
q.popleft() # 左边弹出元素
print(q) # deque([1, 2, 3])
3.默认字典(defaultdict)
默认字典,字典的一个子类,继承所有字典的方法,默认字典在进行定义初始化的时候得指定字典值有默认类型。
from collections import defaultdict
dic = defaultdict(dict)
dic["k1"].update({"asdsa": "123"})
print(dic)
# 字典dic在定义的时候就定义好了值为字典类型,虽然现在字典中还没有键值 k1,但仍然可以执行字典的update方法. 这种操作方式在传统的字典类型中是无法实现的,必须赋值以后才能进行值得更新操作,否则会报错。
4.有序字典(OrderedDict)
有序字典也是字典的一个子类:
传统方式进行字典排序:
# 定义传统字典
dic1 = dict()
# 按顺序添加字典内容
dic1['a'] = '123'
dic1['b'] = 'jjj'
dic1['c'] = '394'
dic1['d'] = '999'
print(dic1) # 结果: {'a': '123', 'c': '394', 'b': 'jjj', 'd': '999'}
# 排序
dic1_key_list = []
for k in dic1.keys():
dic1_key_list.append(k)
dic1_key_list.sort()
for key in dic1_key_list:
print('dic1字典排序结果 %s:%s' % (key, dic1[key]))
使用OrderedDict对字典进行排序:
from collections import OrderedDict
# 定义有序字典
dic2 = OrderedDict()
dic2['a'] = '123'
dic2['b'] = 'jjj'
dic2['c'] = 'abc'
dic2['d'] = '999'
print(dic2) # OrderedDict([('a', '123'), ('b', 'jjj'), ('c', 'abc'), ('d', '999')])
print(dic2.keys()) # odict_keys(['a', 'b', 'c', 'd'])
5.可命名元祖(namedtuple)
namedtuple由自己的类工厂namedtuple()进行创建,而不是由表中的元组进行初始化,通过namedtuple创建类的参数包括类名称和一个包含元素名称的字符串。
方法示例:
from collections import namedtuple
p = namedtuple("person", "name,age,sex")
print(type(p)) # <class 'type'>
zhanglin = p("zhanglin", 30, "male")
print(zhanglin) # person(name='zhanglin', age=30, sex='male')
print(zhanglin.name, zhanglin.age) # zhanglin 30
time模块
在Python中,与时间处理相关的模块有:time、datetime以及calendar。学会计算时间,对程序的调优非常重要,可以在程序中狂打时间戳,来具体判断程序中哪一块耗时最多,从而找到程序调优的重心处。
常用方法:1.time.sleep(secs)。推迟指定的时间运行,单位为秒。2.time.time()。获取当前时间戳。
三种用于表示时间的格式(彼此之间可以转换):
时间戳
距离1970年1月1日0时0分0秒至此相差的秒数。写法:time.time()。
结构化时间
该时间类型主要是给计算机看的,人看起来不太方便。写法:time.localtime()。
| 索引值(Index) | 属性(Attribute) | 值(Values) |
|---|---|---|
| 0 | tm_year(年) | (例如:2015) |
| 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(星期几) | 0 ~ 6(0 表示星期一) |
| 7 | tm_yday(一年中的第几天) | 1 ~ 366 |
| 8 | tm_isdst(是否为夏令时) | 0, 1, -1(-1 代表夏令时)默认为0 |
值得注意的是,索引值为5的tm_sec(秒)的值得范围是可以为0~61的。60 代表闰秒,61 是基于历史原因保留。但是一般不会产生这种情况,了解一下就可以了。
格式化时间
人最容易接收的一种时间格式,比如:2000/1/21 or 11:11:11 写法:time.strftime()
| 格式 | 含义 |
|---|---|
| %a | 本地(locale)简化星期名称 |
| %A | 本地完整星期名称 |
| %b | 本地简化月份名称 |
| %B | 本地完整月份名称 |
| %c | 本地相应的日期和时间表示 |
| %d | 一个月中的第几天(01 - 31) |
| %H | 一天中的第几个小时(24 小时制,00 - 23 |
| %l | 一天中的第几个小时(12 小时制,01 - 12) |
| %j | 一年中的第几天(001 - 366) |
| %m | 月份(01 - 12) |
| %M | 分钟数(00 - 59) |
| %p | 本地 am 或者 pm 的相应符 |
| %S | 秒(01 - 61) |
| %U | 一年中的星期数(00 - 53 星期天是一个星期的开始)第一个星期天之前的所有天数都放在第 0 周 |
| %w | 一个星期中的第几天(0 - 6,0 是星期天) |
| %W | 和 %U 基本相同,不同的是 %W 以星期一为一个星期的开始 |
| %x | 本地相应日期 |
| %X | 本地相应时间 |
| %y | 去掉世纪的年份(00 - 99) |
| %Y | 完整的年份 |
| %z | 用 +HHMM 或 -HHMM 表示距离格林威治的时区偏移(H 代表十进制的小时数,M 代表十进制的分钟数) |
| %Z | 时区的名字(如果不存在为空字符) |
| %% | %号本身 |
时间类型的转换
**时间格式转换图:

时间戳与结构化时间的转换
# gmtime
# localtime
print(time.localtime(1648551245.638347)) # 将时间戳转化为结构化时间
# time.struct_time(tm_year=2022, tm_mon=3, tm_mday=29, tm_hour=18, tm_min=54, tm_sec=5, tm_wday=1, tm_yday=88, tm_isdst=0)
# 使用gmtime结果一样,效果相同的
结构化时间与格式化时间的转换
import time
# strftime
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) # 将结构化时间转化为格式化时间 2022-03-29 18:57:23
# strptime
print(time.strptime('2022-03-29 18:57:23', '%Y-%m-%d %X')) # 将格式化时间转化为结构化时间
# time.struct_time(tm_year=2022, tm_mon=3, tm_mday=29, tm_hour=18, tm_min=57, tm_sec=23, tm_wday=1, tm_yday=88, tm_isdst=-1)
datetime模块
datetime 模块提供了各种类用于操作日期和时间,该模块侧重于高效率的格式化输出。
基本操作:
import datetime
print(datetime.date.today()) # 2022-03-29
print(datetime.datetime.today()) # 2022-03-29 19:01:35.054007
'''
date 意思就是年月日
datetime 意思就是年月日 时分秒
# 后期很多时间相关的操作都是跟date和time有关系
'''
res = datetime.date.today()
print(res.year) # 2022
print(res.month) # 3
print(res.day) # 29
print(res.weekday()) # 1 星期0-6
print(res.isoweekday()) # 2 星期1-7
ctime = datetime.datetime.today()
time_tel = datetime.timedelta(days=4) # 有很多时间选项
print(ctime) # 2022-03-29 19:06:12.752012
print(ctime + time_tel) # 2022-03-29 19:06:12.752012
print(ctime - time_tel) # 2022-03-29 19:06:12.752012
res = ctime + time_tel
print(res - ctime) # 4 days, 0:00:00
# 这是一个针对时间计算的公式:日期对象 = 日期对象 +/- timedelta对象
random模块
Python中的random模块用于生成随机数。
random模块的功能
1.random.random()
用于生成一个0到1的随机浮点数:0<= n < 1.0
import random
print(random.random()) # 0.6475660665971071 随机产生
2.random.uniform(a,b)
用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成的随机数n: b <= n <= a。如果 a <b, 则 a <= n <= b。
import random
print(random.uniform(2, 4)) # 3.8782705354832148
3.random.randint(a, b)
用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
import random
print(random.randint(0,9)) # 5 随机产生一个0到9之间的整数(包含0和9)
4.random.choice(sequence)
random.choice从序列中获取一个随机元素。其函数原型为:random.choice(sequence)。
import random
a = ['Jason', 'handsome', 'nb', '666']
print(random.choice(a)) # handsome 随机抽取一个
5.random.sample(sequence, k)
从指定序列中随机获取指定长度的片断并随机排列。注意:sample函数不会修改原有序列。
import random
a = ['Jason', 'handsome', 'nb', '666']
print(random.sample(a, 3)) # ['handsome', '666', 'Jason'] 随机指定个数抽样

学习内容总结
浙公网安备 33010602011771号