目录
一、collections 简介
二、namedtuple - 函数创建自定义元祖类型
三、deque - 队列和栈的实现
3-1 deque(maxlen = N) 固定长度的队列应用
四、defaultdict - 字典类型,若查找的key不存在,不报错而返回默认值。
五、OrderedDict - 字典类型,保持字典内key顺序按照插入的顺序排列
六、Counter - 字典类型,查询对象的出现次数,以字典方式存储
七、ChainMap - 管理多个映射对象,对外表现单独的映射结构
一、collections 简介
官方文档
这个模块实现了特定目标的容器,以提供Python标准内建容器 dict、list、set、tuple 的替代选择。
nametuple() 创建命名元组子类的工厂函数 deque 类似列表的容器,但是实现了两端的快去添加(append)和删除(pop) ChainMap 类字典,将多个映射集合到一个视图里面 Counter 字典的子类,提供了可hashUI想的计数功能 OrderedDict 字典的子类,保存了被添加的顺序 defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值 UserDict 封装了字典对象,简化了字典子类化 UserList 封装了列表对象,简化了列表子类化 UserString 封装了列表对象,简化了字符串子类化
二、namedtuple - 函数创建自定义元祖类型
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None) # 创建元组表示点的坐标 point = collections.namedtuple('point',['x','y']) p = point(1,2) print(p.x,p.y) # 创建元组表示圆的坐标和半径 circle = collections.namedtuple('circle',['x','y','r']) c = circle(0,0,4) print(c.x,c.y,c.r)
三、deque - 队列和栈的实现
队列 vs 列表:队列两端添加或弹出元素,复杂度都为O(1);列表的头部插入或移除元素,复杂度为O(N)
# 创建deque类型的列表 deq = collections.deque(['a','b','c']) print(deq) # 正常插入右端数据 deq.append(1) print(deq) # 插入左端数据 deq.appendleft(2) print(deq) # 正常删除右端数据 deq.pop() print(deq) # 删除左端数据 deq.popleft() print(deq)
3-1 deque(maxlen = N) 固定长度的队列应用
固定队列,当有新纪录加入已满队列时,会自动移除最老的记录,以插入新记录
使用固定队列的优点(相比列表上的手动append和del):较为优雅、运行速度快
from collections import deque # 对 lines 文本行进行 pattern 关键词匹配,并输出当前匹配行以及最后检查的 history 行文本 # 仅返回第一个匹配成功的生成器对象 def search(lines, pattern, history=5): previous_line = deque(maxlen=history) for line in lines: # 若关键词在文本行内,yield 跳出循环,返回生成器对象 if pattern in line: yield line, previous_line # 否则将文本行持续添加到固定队列,固定队列内持续保持最新的最后五行文本 previous_line.append(line) if __name__ == '__main__': # with open('test.txt')as f: # for line, prevlines in search(f, 'python', 5): # for pline in prevlines: # print(pline, end='') # print(line, end='') # print('-' * 20) with open('test.txt')as f: genobj = search(f, 'python', 5) print(genobj.__next__()) # ('python\n', deque(['11111\n', '123\n'], maxlen=5)) for line, prelines in genobj: print(line) # python print(prelines) # deque(['11111\n', '123\n', 'python\n', 'hello\n', 'world\n'], maxlen=5) print(list(prelines)) # ['11111\n', '123\n', 'python\n', 'hello\n', 'world\n'] for pline in prelines: print('deque 列表值:', pline)
四、defaultdict - 字典类型,若查找的key不存在,不报错而返回默认值。
''' defaultdict 字典类型,若查找的key不存在,不报错而返回默认值。 defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值 ''' # first argument must be callable or None dd = collections.defaultdict(list) # dd = collections.defaultdict(lambda: 'N/A') print(dd) # defaultdict(
, {}) dd['a'] = 123 print(dd['a']) # 123 print(dd['b']) # []
五、OrderedDict - 字典类型,保持字典内key顺序按照插入的顺序排列
''' OrderedDict 字典类型,保持字典内key顺序按照插入的顺序排列。 注:OrderedDict的大小是普通字典的2倍多,因为它额外创建了链表 ''' l = [('a', 1), ('b', 2), ('c', 3)] # 初始化一个od类型字典 od = collections.OrderedDict(l) print(od) # OrderedDict([('a', 1), ('b', 2), ('c', 3)]) od['d'] = 4 print(od) # OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) print(type(od)) #
print(od.values()) # odict_values([1, 2, 3, 4]) print(od.keys()) # odict_keys(['a', 'b', 'c', 'd']) print(od.items()) # odict_items([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) print(od['a']) # 1
六、Counter - 字典类型,查询对象的出现次数,以字典方式存储
''' Counter 字典类型,简单的计数器(记录查询对象出现的次数,以字典方式存储) c = Counter(计算对象) c[任何可哈希对象作为输入] ''' # ---------------------------------------------------------------- # 简单计算字符串中出现的字符,自增 c = collections.Counter() print(c) # Counter() for ch in 'hello python': c[ch] = c[ch] + 1 print(c) ''' 简单的计算字符串中出现的字符,update()更新''' c = collections.Counter('hello python') print(c) # Counter({'h': 2, 'l': 2, 'o': 2, 'e': 1, ' ': 1, 'p': 1, 'y': 1, 't': 1, 'n': 1}) c.update('hello world!') print(c) # Counter({'l': 5, 'o': 4, 'h': 3, 'e': 2, ' ': 2, 'p': 1, 'y': 1, 't': 1, 'n': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1}) '''筛选符合条件次数的keys''' words = ['a', 'hello', 'my', 'wold', 'around', 'the', 'hello', 'look', 'a'] word_c = collections.Counter(words) # 获取指定对象出现的次数 print(word_c['my']) # 1 print(word_c['a']) # 2 # 用 most_common 筛选出现两次的单词 top_two = word_c.most_common(2) print(top_two) # [('a', 2), ('hello', 2)] '''使用数学运算符,进行字典运算''' a = collections.Counter('hello') b = collections.Counter('hello,python') print(a, b) # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) # Counter({'h': 2, 'l': 2, 'o': 2, 'e': 1, ',': 1, 'p': 1, 'y': 1, 't': 1, 'n': 1}) c = a + b print(c) # Counter({'l': 4, 'h': 3, 'o': 3, 'e': 2, ',': 1, 'p': 1, 'y': 1, 't': 1, 'n': 1}) d = b - a print(d) # Counter({'h': 1, 'o': 1, ',': 1, 'p': 1, 'y': 1, 't': 1, 'n': 1})
七、ChainMap - 管理多个映射对象,对外表现单独的映射结构
''' ChainMap 管理多个映射对象,在一个字典内创建多个映射数据,但对外表现为一个单独的映射结构。 ''' a = {'x': 1, 'z': 3} b = {'y': 2, 'z': 4} cm = collections.ChainMap(a, b) print(cm) # ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}) print(cm['x']) # 1 print(cm['y']) # 2 # 若有重复的键,采用第一个映射中所对应的值 print(cm['z']) # 3 print(len(cm)) # 3 print(list(cm.keys())) # ['y', 'z', 'x'] print(list(cm.values())) # [2, 1, 3] # 修改映射的操作,只会作用在列出的第一个映射结构上。 即只对原主进行增删改查操作 cm['x'] = 333 cm['m'] = 444 # del cm['y'] #KeyError: "Key not found in the first mapping: 'y'" print(cm) # ChainMap({'x': 333, 'z': 3, 'm': 444}, {'y': 2, 'z': 4}) print(a) # {'x': 333, 'z': 3, 'm': 444} ''' maps :返回用户可更新的映射对象列表。 在这个列表里包括所有添加的映射对象,可以更新任何一个列表里显示的映射对象。 在这个属性至少会包括一个映射对象。 ''' print(cm.maps) # [{'x': 333, 'z': 3, 'm': 444}, {'y': 2, 'z': 4}] # 进行修改也是对原字典进行修改 cm.maps[0]['z'] = 2222 print(cm.maps) # [{'x': 333, 'z': 2222, 'm': 444}, {'y': 2, 'z': 4}] print(a) # {'x': 333, 'z': 2222, 'm': 444} ''' new_child(m=None):在原来的chainmap内创建新的映射对象,m为初始字典。对子映射的修改,则只会修改新的子映射字典。 可以用来创建同名子映射,用来修改值,而不会对原有属性进行修改 ''' print(cm.new_child()) # ChainMap({}, {'x': 333, 'z': 2222, 'm': 444}, {'y': 2, 'z': 4}) cm_a = cm.new_child({'xyz':123}) cm['x'] = 0 cm_a['z'] = 9999 print(cm) # ChainMap({'x': 0, 'z': 2222, 'm': 444}, {'y': 2, 'z': 4}) print(cm_a) # ChainMap({'xyz': 123, 'z': 9999}, {'x': 0, 'z': 2222, 'm': 444}, {'y': 2, 'z': 4}) # 创建同名子映射,之后的修改只会对新的映射进行修改 cm = cm.new_child({'xyz': 11111}) print(cm) # ChainMap({'xyz': 11111}, {'x': 333, 'z': 2222, 'm': 444}, {'y': 2, 'z': 4})