collections 模块是 Python 标准库中的一个模块,提供了高效的容器数据类型,这些类型扩展了 Python 内置的标准数据类型,如列表、字典和元组。collections 模块中的数据结构不仅提高了代码的可读性,还在特定的应用场景中提高了性能。
collections模块中的数据类型包括:
- 命名元组(NamedTuple)。命名元组(在Python 3.6+中通过NamedTuple引入,Python 3.7+中直接集成到collections模块)提供了一种类似于元组的容器,但它允许你通过属性名而非索引来访问元素。这使得代码更加清晰和易于维护。
- 计数器(Counter)。Counter是一个字典的子类,用于计数可哈希对象。它是一个集合,其中元素被存储为字典的键,而它们的计数作为字典的值。Counter类提供了一系列方法来方便地处理计数数据,如计算元素的总和、更新计数、以及计算两个Counter对象的交集、并集和差集。
- 有序字典(OrderedDict)。OrderedDict是一个字典的子类,它记住了元素被添加到字典中的顺序。当迭代OrderedDict时,元素将按照它们被添加的顺序返回,这与普通字典不同,后者不保证元素的顺序。
- 默认字典(DefaultDict)。DefaultDict为字典中的每个键提供了一个默认值。当你尝试访问一个不存在的键时,DefaultDict会返回该键对应的默认值,而不是抛出一个KeyError。这避免了在访问字典之前需要显式地检查键是否存在的需要。
- 双端队列(deque)。deque(发音为“deck”或“double-ended queue”)是一个双端队列,它支持从两端快速添加(append)和弹出(pop)元素。这使得deque成为实现队列和栈的理想选择,同时也适用于其他需要高效插入和删除操作的场景。
- 链式映射(ChainMap)。ChainMap允许你将多个字典链接在一起,这样你就可以将它们当作一个单一字典来查找值。当在一个ChainMap中查找键时,它会在链接的字典中从左到右查找,直到找到该键为止。这对于在多个字典中查找数据而不希望合并它们时非常有用。
- 用户定义的映射类型(UserDict, UserList, UserString)。虽然这些类在Python 3.3及以后版本中被标记为过时(建议使用abc中的抽象基类来创建自定义容器),但它们曾经提供了一种方式,允许用户以面向对象的方式创建自定义的字典、列表和字符串类型。现在,推荐使用collections.abc模块中的MutableMapping、MutableSequence和MutableSet等抽象基类来定义自定义容器。
namedtuple()
namedtuple() 是一个工厂函数,用于创建具有命名字段的元组子类。它使得元组的每个字段可以通过名字而不仅仅是索引来访问。
主要特点:
- 字段访问:可以通过字段名称访问值,如x。
- 不变性:命名元组是不可变的,创建后不能更改其中的元素。
- 可迭代:可以像普通元组一样迭代。
- 自定义方法:可以定义 __repr__() 和 __str__() 方法以便于打印和调试。
用法:
from collections import namedtuple # 创建一个名为 'Point' 的命名元组 Point = namedtuple('Point', ['x', 'y']) # 创建一个 Point 实例 p = Point(10, 20) # 访问字段 print(p.x) # 输出: 10 print(p.y) # 输出: 20
deque
deque(双端队列)是一个线程安全的、可以从两端快速添加和删除元素的双端队列数据结构。与列表相比,deque 在两端的操作时间复杂度为 O(1),而列表在头部操作时间复杂度为 O(n)。
主要特点:
- 双端操作:支持从两端快速添加和删除元素。
- 旋转操作:支持向左或向右旋转元素。
- 线程安全:适用于多线程环境。
用法:
from collections import deque # 创建一个 deque 实例 d = deque([1, 2, 3]) # 从右侧添加元素 d.append(4) print(d) # 输出: deque([1, 2, 3, 4]) # 从左侧添加元素 d.appendleft(0) print(d) # 输出: deque([0, 1, 2, 3, 4]) # 从右侧删除元素 d.pop() print(d) # 输出: deque([0, 1, 2, 3]) # 从左侧删除元素 d.popleft() print(d) # 输出: deque([1, 2, 3]) # 旋转 deque d.rotate(1) # 向右旋转 print(d) # 输出: deque([3, 1, 2]) d.rotate(-1) # 向左旋转 print(d) # 输出: deque([1, 2, 3])
Counter
Counter 是一个子类化的字典,用于计数可哈希对象。它的主要用途是统计元素的出现频率。
主要特点:
- 计数功能:自动处理计数任务。
- 常用操作:如 most_common() 方法可以获取出现频率最高的元素。
- 支持数学运算:支持与其他 Counter 对象的加法、减法等运算。
用法:
from collections import Counter # 创建一个 Counter 实例 c = Counter('abracadabra') # 获取元素计数 print(c) # 输出: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) # 获取最常见的 2 个元素 print(c.most_common(2)) # 输出: [('a', 5), ('b', 2)] # 更新计数 c.update('abc') print(c) # 输出: Counter({'a': 6, 'b': 3, 'r': 2, 'c': 2, 'd': 1}) # 减少计数 c.subtract('a') print(c) # 输出: Counter({'a': 5, 'b': 3, 'c': 2, 'r': 2, 'd': 1})
OrderedDict
OrderedDict 是一个字典的子类,它保留了元素的插入顺序。标准字典在 Python 3.7 之后也保持插入顺序,但在之前的版本中,OrderedDict 提供了这个功能。
主要特点:
- 保持顺序:保留元素的插入顺序。
- 方法支持:提供 move_to_end() 方法来改变元素的位置。
用法:
from collections import OrderedDict # 创建一个 OrderedDict 实例 od = OrderedDict() od['a'] = 1 od['b'] = 2 od['c'] = 3 # 输出按插入顺序排列的字典 print(od) # 输出: OrderedDict([('a', 1), ('b', 2), ('c', 3)]) # 插入新元素 od['d'] = 4 print(od) # 输出: OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) # 移动到末尾 od.move_to_end('a') print(od) # 输出: OrderedDict([('b', 2), ('c', 3), ('d', 4), ('a', 1)])
defaultdict
defaultdict 是 dict 的一个子类,它提供了一个默认值工厂函数。如果尝试访问字典中不存在的键,会自动使用工厂函数创建一个默认值。
主要特点:
- 自动默认值:当访问不存在的键时,自动生成默认值。
- 灵活工厂函数:可以使用各种工厂函数,如 list、int、set 等。
用法:
from collections import defaultdict # 创建一个 defaultdict 实例,默认值为列表 dd = defaultdict(list) # 添加元素 dd['a'].append(1) dd['b'].append(2) dd['a'].append(3) print(dd) # 输出: defaultdict(<class 'list'>, {'a': [1, 3], 'b': [2]}) # 默认值工厂函数返回的默认值 print(dd['c']) # 输出: []
ChainMap
ChainMap 是一个字典视图,用于将多个字典或映射合并为一个视图。它允许你在多个映射之间进行查找操作,而不需要实际合并这些映射。
主要特点:
- 虚拟合并:将多个映射合并为一个视图。
- 查找顺序:查找时按照创建顺序从前到后。
用法:
from collections import ChainMap # 创建多个字典 dict1 = {'a': 1, 'b': 2} dict2 = {'b': 3, 'c': 4} # 创建 ChainMap 实例 cm = ChainMap(dict1, dict2) # 查找值 print(cm['a']) # 输出: 1 print(cm['b']) # 输出: 2 (dict1 中的值覆盖了 dict2 中的值) print(cm['c']) # 输出: 4 # 添加新字典 dict3 = {'d': 5} cm = cm.new_child(dict3) print(cm['d']) # 输出: 5
UserDict
UserDict 是一个用于创建自定义字典类的基类。它实际上是一个对内置字典对象的包装器,允许用户通过继承来实现自己的字典行为。
- 实现: UserDict 内部维护一个实际的字典对象 data,所有的操作都会委托给这个字典。
- 用途: 通过继承 UserDict,可以很容易地定制字典的行为,比如修改键值对的添加、删除、查找等操作。
from collections import UserDict class MyDict(UserDict): def __setitem__(self, key, value): print(f'Setting {key} to {value}') super().__setitem__(key, value) my_dict = MyDict() my_dict['a'] = 10 # 输出: Setting a to 10
UserList
UserList 是一个用于创建自定义列表类的基类。类似于 UserDict,它是对内置列表的包装,提供了一个简单的方式来定制列表的行为。
- 实现: UserList 维护一个实际的列表对象 data,所有的操作都会委托给这个列表。
- 用途: 继承 UserList 可以定制列表的添加、删除、排序等操作。
from collections import UserList class MyList(UserList): def append(self, item): print(f'Appending {item}') super().append(item) my_list = MyList() my_list.append(1) # 输出: Appending 1
UserString
UserString 是一个用于创建自定义字符串类的基类。它是对内置字符串的包装,允许用户定制字符串的操作。
- 实现: UserString 内部维护一个字符串对象 data,所有的字符串操作都会委托给这个对象。
- 用途: 继承 UserString 可以定制字符串的拼接、替换、大小写转换等操作。
from collections import UserString class MyString(UserString): def __str__(self): return self.data.upper() my_string = MyString("hello") print(my_string) # 输出: HELLO
参考链接: