【python 内置模块】collections

2024-01-20 00:00:00

目录:

collections 模块提供了一系列专用的容器数据类型,作为对 Python 内置容器(如 dict、list、set、tuple)的补充和增强。

namedtuple 命名元组

namedtuple 是一个工厂函数,用于创建具有命名字段的轻量级、不可变对象。

本质上是元组的子类,但允许通过属性名而非索引来访问元素,极大地增强了代码的可读性和自文档性,在定义简单数据结构(如坐标点、记录等)时非常有用。

from collections import namedtuple

# 定义一个名为“Point”的命名元组,字段为x和y
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, y=20)
print(p.x, p.y)  # 输出: 10 20
print(p[0] + p[1])  # 仍支持索引访问,输出: 30

第二个参数可以是包含多个字段的字符串,不同字段之间用空格隔开;

from collections import namedtuple

User = namedtuple('User', 'name age gender')
user = User('Alice', 18, 'female')
print(user) # User(name='Alice', age=18, gender='female')
print(user.name)    # Alice
print(user[1])  # 18

deque 双端队列

实现在两端快速添加和弹出元素的线性数据结构,相比于 list,deque 在需要队列或栈功能的场景下性能更优。

from collections import deque

d = deque([1, 2, 3, 4, 5])
d.appendleft(0)   # 在左侧添加元素
d.append(6)       # 在右侧添加元素
print(d)          # 输出: deque([0, 1, 2, 3, 4, 5, 6])

d.popleft()       # 从左侧弹出元素
d.pop()           # 从右侧弹出元素
print(d)          # 输出: deque([1, 2, 3, 4, 5])

Counter 计数器

Counter 接收一个可迭代对象(如列表、字符串)或映射作为输入,并返回一个字典,其中键是元素,值是元素出现的次数。

它提供了如 most_common()、elements()、subtract() 和 update() 等实用方法,使得频率统计变得异常简单。

from collections import Counter

# 统计列表元素频率
data = ['apple', 'banana', 'orange', 'apple', 'banana', 'apple']

cnt = Counter(data)
print(cnt)  # 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})

# 获取出现频率最高的两个元素
print(cnt.most_common(2))  # 输出: [('apple', 3), ('banana', 2)]

# 统计字符串字符频率
print(Counter('hello world'))  # 输出: Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})

defaultdict 带默认值的字典

defaultdict 是 dict 的子类。在初始化时接受一个可调用对象作为参数。当尝试访问一个不存在的键时,defaultdict 会自动调用这个工厂函数,将返回值作为该键的默认值插入字典,从而避免抛出 KeyError 异常。这极大地简化了诸如分组、累加等操作的代码。

from collections import defaultdict

# 使用 list 作为默认工厂,用于将键映射到值列表
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
    d[k].append(v)  # 即使键不存在,也会自动创建空列表
print(dict(d))  # 输出: {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}

# 使用int作为默认工厂(默认值为0),用于计数
fruit_count = defaultdict(int)
fruit_count['apple'] += 2  # 键不存在时,初始值为 0,然后加 2
print(fruit_count['banana'])  # 输出: 0 (访问不存在的键,返回默认值 0)

OrderedDict 有序字典

OrderedDict 是 dict 的子类,它会记住键值对被插入的顺序。在 Python 3.7 之前,内置的 dict 不保证顺序,因此 OrderedDict 是必需的。从Python 3.7 开始,内置 dict 正式成为有序字典,但 OrderedDict 仍然在某些场景下有用,例如它提供了 move_to_end() 等方法,以及对相等性判断的差异(OrderedDict 会考虑顺序)

from collections import OrderedDict

od = OrderedDict()
od['a'] = 1
od['c'] = 3
od['b'] = 2
for key, value in od.items():
    print(key, value)  # 输出顺序保证为: a 1, c 3, b 2

ChainMap 链式映射

ChainMap 类可以将多个字典或其他映射组合成一个单一的、可更新的视图。在进行键查找时,它会按照传入映射的顺序从第一个映射开始搜索,直到找到为止。这对于管理多层配置(如命令行参数、环境变量、默认配置)或模拟嵌套作用域非常有用。

from collections import ChainMap

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

chain = ChainMap(dict1, dict2)
print(chain)    # 输出: ChainMap({'a': 1, 'b': 2}, {'b': 3, 'c': 4})
print(chain['a'])  # 输出: 1 (来自 dict1)
print(chain['b'])  # 输出: 2 (来自 dict1,因为 dict1 先被搜索)
print(chain['c'])  # 输出: 4 (来自 dict2)

# 更新只影响第一个映射
chain['b'] = 10
print(dict1)  # 输出: {'a': 1, 'b': 10}
print(dict2)  # 输出: {'b': 3, 'c': 4}

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: