Python - collections 模块 - 内置的集合类模块

目录

一、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})

你可能感兴趣的:(python)