跳到主要内容

collections

collections 提供了比列表、元组和普通字典更适合特定场景的容器。常用类型有 Counter、defaultdict、deque、namedtuple 和 OrderedDict。

Counter:计数器​

Counter 接收可迭代对象或映射,统计每个元素出现次数:

from collections import Counter

counts = Counter("banana")
print(counts) # Counter({'a': 3, 'n': 2, 'b': 1})
print(counts["a"], counts["x"]) # 3 0(不存在的键返回 0)
print(counts.most_common(2)) # [('a', 3), ('n', 2)]

update() 增加计数,subtract() 减少计数;它们接收的是元素而不是“替换字典”。elements() 返回按计数重复的元素,零或负数计数不会产生元素。

left = Counter(a=3, b=1)
right = Counter(a=1, b=2)
print(left + right) # Counter({'a': 4, 'b': 3})
print(left - right) # Counter({'a': 2}),只保留正数
print(left & right) # 交集取较小计数
print(left | right) # 并集取较大计数

defaultdict:自动提供默认值​

当访问不存在的键时,defaultdict 调用工厂函数创建默认值,适合分组和聚合:

from collections import defaultdict

groups = defaultdict(list)
for name, team in [("小林", "A"), ("小周", "B"), ("小陈", "A")]:
groups[team].append(name)
print(dict(groups)) # {'A': ['小林', '小陈'], 'B': ['小周']}

工厂可以是 int、set 或自定义函数。注意,groups["C"] 会改变字典;只检查是否存在时使用 "C" in groups 或 groups.get("C")。

deque:双端队列​

deque 在两端追加和弹出都是 O(1),适合队列、栈和滑动窗口:

from collections import deque

queue = deque([1, 2])
queue.append(3)
queue.appendleft(0)
print(queue.popleft()) # 0
print(queue.pop()) # 3

recent = deque(maxlen=3)
for value in [10, 20, 30, 40]:
recent.append(value)
print(recent) # deque([20, 30, 40])

rotate(n) 可循环移动元素,extendleft() 会反向加入可迭代对象。随机索引访问中间元素不如列表高效。

namedtuple 与其他类型​

namedtuple 创建轻量、不可变的元组子类,字段可用名称访问:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y, p._asdict())

新项目通常优先使用 dataclasses.dataclass,因为它支持默认值、类型注解和可变对象。OrderedDict 在现代 Python 中很少需要,普通 dict 已保证插入顺序;但 move_to_end() 和顺序敏感的相等比较仍是它的特色。

选择建议​

需求推荐类型
统计频次、取 Top NCounter
按键分组并自动初始化defaultdict
两端进出、限长历史deque
不可变记录对象namedtuple
需要移动键或顺序比较OrderedDict