> 文档中心 > Python模块-collections

Python模块-collections

目录

    • 概述
    • 一、namedtuple()
    • 二、deque()
    • 三、OrderDict
    • 四、defaultdict()
    • 五、Counter
    • 六、ChainMap
    • 七、UserDict、UserList、UserString

概述

collections模块实现了特定的数据容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。

collections模块的文档注释中解释了相关容器类的主要用途

__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap']'''This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict, list, set, and tuple.* namedtuple   factory function for creating tuple subclasses with named fields* deque list-like container with fast appends and pops on either end* ChainMap     dict-like class for creating a single view of multiple mappings* Counter      dict subclass for counting hashable objects* OrderedDict  dict subclass that remembers the order entries were added* defaultdict  dict subclass that calls a factory function to supply missing values* UserDict     wrapper around dictionary objects for easier dict subclassing* UserList     wrapper around list objects for easier list subclassing* UserString   wrapper around string objects for easier string subclassing'''
容器 用途
namedtuple 创建命名元组子类的工厂函数
deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
OrderDict 字典的子类,保存了他们被添加的顺序
defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值
Counter 字典的子类,提供了可哈希对象的计数功能
ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面
UserDict 封装了字典对象,简化了字典子类化
UserList 封装了列表对象,简化了列表子类化
UserString 封装了字符串对象,简化了字符串子类化

一、namedtuple()

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

元组(tuple)不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义。namedtuple(具名元组)则为每个成员分配名称索引以及数字索引。namedtuple比普通tuple具有更好的可读性,可以使代码更易于维护。同时与字典相比,又更加的轻量和高效。
例如以下案例我们使用namedtuple建立这样的数据结构,每一个对象是拥有三个元素的tuple。使用namedtuple方法就可以方便的通过tuple来生成可读性更高也更好用的数据结构。

import collectionsPerson = collections.namedtuple('Person', ['name', 'age', 'gender'])bob = Person(name='Bob', age=15, gender='male')print(bob)print(type(bob))# 输出Person(name='Bob', age=15, gender='male')<class '__main__.Person'>

二、deque()

deque([iterable[, maxlen]]) --> deque object
  • deque返回一个新的双向队列对象,从左到右初始化(用方法 append()) ,从 iterable (迭代对象) 数据创建。如果 iterable 没有指定,新队列为空。
  • deque队列是由栈或者queue队列生成的,支持线程安全。内存高效添加(append)和弹出(pop),从两端都可以操作数据,与列表list相似。
  • dequelist的区别在于:头部插入与删除的时间复杂度为O(1)

deque支持的操作主要包括:

append(x): 添加x到右端appendleft(x): 添加x到左端insert(i,x): 在位置i插入xpop(): 移去并且返回deque最右侧的那一个元素popleft(): 移去并且返回deque最左侧的那一个元素count(x): 计算 deque 中元素等于x的个数......有关于deque更多操作可参见Python官方文档:https://docs.python.org/zh-cn/3/library/collections.html#deque-objects

示例代码如下:

from collections import dequea = deque([10, 20, 30, 40])a.appendleft(0)print(a)a.append(50)print(a)a.pop()print(a)a.popleft()print(a)# 输出deque([0, 10, 20, 30, 40])deque([0, 10, 20, 30, 40, 50])deque([0, 10, 20, 30, 40])deque([10, 20, 30, 40])

三、OrderDict

OrderDict有序字典类似于普通字典, 但是它会记住首次插入键的顺序。OrderedDict在迭代操作的时候会保持元素被插入时的顺序,其内部维护着一个根据键插入顺序排序的双向链表,每次当一个新的元素插入进来的时候,它会被放到链表的尾部。由于内部需要维护另外一个链表,OrderDict对象占用的内存是普通字典的2倍。

from collections import OrderedDicta = OrderedDict()a['A'] = 10a['B'] = 12a['C'] = 11a['D'] = 13print(a)# 输出OrderedDict([('A', 10), ('B', 12), ('C', 11), ('D', 13)])

四、defaultdict()

defaultdict(default_factory[, ...]) --> dict with default factory

这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,而相同情况下dict()会返回KeyError

from collections import defaultdictdef default_value():    return 0a = defaultdict(default_value)b = dict()print(a[1])print(b[1])# 输出0KeyError: 1

1.使用int作为默认工厂

如果我们将int传递给defaultdict()函数,则可以形成一个value为整数的字典。

name = 'Bubbles'mydict = defaultdict(int)  # 创建一个value为整数类型的字典for i in name:    mydict[i] += 1print(mydict)# 输出defaultdict(<class 'int'>, {'B': 1, 'u': 1, 'b': 2, 'l': 1, 'e': 1, 's': 1})

2.使用list作为默认工厂

如果我们将list(不带引号)传递给defaultdict()函数,则可以形成一个value为列表的字典。

a = [('a', 1), ('b', 2), ('c', 3)]mylist = defaultdict(list)  # 创建一个value为列表类型的字典for i, j in a:    mylist[i].append(j)print(mylist)# 输出defaultdict(<class 'list'>, {'a': [1], 'b': [2], 'c': [3]})

五、Counter

Counter是dict的一个子类,用于对可哈希对象进行计数。任意长度的输入通过哈希算法变换成固定长度的输出,该输出就是哈希值。在Python中:

  • 可哈希的数据类型,即不可变的数据结构(数字类型(int,float,bool)字符串str、元组tuple、自定义类的对象)。
  • 不可哈希的数据类型,即可变的数据结构 (字典dict,列表list,集合set)
  • 字典的键必须是可哈希的、set中的内容也需要可哈希对象。

Counter类中重写或实现了6种方法

  • most_common(self, n=None): 列出n个最常见的元素及其计数。如果n为None,则按频率从高到低列出所有元素的计数。
  • elements(self): 为Counter中的值返回一个迭代器对象。
  • from_keys(cls, iterable, v=None):
  • update(*args, **kwds): 类似于dict.update(),但添加计数而不是替换计数。参数可以是一个可迭代对象、一个字典或另一个Counter实例
  • subtract(*args, **kwds): 类似于dict.update(),但是是减法而不是替换计数,计数可以减少到零以下。输入和输出都是允许包含0和负数计数。参数可以是一个可迭代对象、一个字典或另一个Counter实例。
  • copy(self): 返回一个浅拷贝。

1. 初始化Python计数器

from collections import Countera = Counter(['a', 'b', 'c', 'a', 'b', 'a'])  # 使用列表初始化计数器b = Counter(('a', 'b', 'c', 'a', 'b', 'a'))  # 使用元组初始化计数器c = Counter("Hello")  # 使用字符串初始化计数器d = Counter({'a': 3, 'b': 2, 'c': 1})  # 使用字典手动地告诉计数器的值e = Counter(a=3, b=2, c=1)  # 使用关键字参数print(a)print(b)print(c)print(d)print(e)# 输出Counter({'a': 3, 'b': 2, 'c': 1})Counter({'a': 3, 'b': 2, 'c': 1})Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1})Counter({'a': 3, 'b': 2, 'c': 1})Counter({'a': 3, 'b': 2, 'c': 1})

2. 更新Counter计数器

from collections import Countera = Counter("Hello")a.update({'e': 2, 'o': 4})  # 更新计数器b = a.most_common(2)  # 取出频率最高的2个值print(a)print(a['e'])  # 访问计数器print(b)for i in "Hello":    print(i, a[i])# 输出Counter({'o': 5, 'e': 3, 'l': 2, 'H': 1})3[('o', 5), ('e', 3)]H 1e 3l 2l 2o 5

六、ChainMap

ChainMap 类可以将多个映射快速的链接到一起,这样它们就可以作为一个单元处理,它通常比创建一个新字典和多次调用 update() 要快很多。

from collections import ChainMapa = {'x': 1, 'y': 3}b = {'z': 2, 'w': 4}c = ChainMap(a, b)print(c)c['x'] = 10print(c)# 输出ChainMap({'x': 1, 'y': 3}, {'z': 2, 'w': 4})ChainMap({'x': 10, 'y': 3}, {'z': 2, 'w': 4})

七、UserDict、UserList、UserString

此三类分别是对 dict、list、str 三种数据类型的包装,其主要是为方便用户实现自己的数据类型,这三个类都是基类,如果用户要扩展这三种类型,只需继承这三个类即可。

参考资料
[1]: https://docs.python.org/zh-cn/3/library/collections.html#counter-objects
[2]: https://zhuanlan.zhihu.com/p/51327766