Collections (增强数据结构)
collections 是 Python 标准库中功能最强的“增强数据结构”模块。
提供比 list / dict / tuple 更专业的数据类型。
| 名称 | 类型 | 作用 |
|---|---|---|
| namedtuple | 元组子类 | 具名字段,轻量结构体 |
| deque | 双端队列 | 快速 append/pop,适合队列 FIFO/LIFO |
| Counter | 计数器 | 用于频次统计(字符串、列表) |
| OrderedDict | 有序字典(Py3.7+ dict 也有序) | 专业字典操作 |
| defaultdict | 默认值字典 | 访问不存在 key 时自动创建值 |
| ChainMap | 多 dict 合并视图 | 多层配置组合、作用域链 |
| UserDict / UserList / UserString | 可继承容器 | 让容器更容易被继承、扩展 |
最佳场景:
- 替代 class
- 替代 dict
- 轻量、不可变、内存占用小
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)
特点:
- 支持索引
- 支持属性访问
- 支持解包
- 不可变(线程安全)
list.append/pop 在头部操作很慢
deque 在两端都 O(1)
from collections import deque
dq = deque([1, 2, 3])
dq.append(4)
dq.appendleft(0)
print(dq)
常用方法:
- append, appendleft
- pop, popleft
- rotate(n)
- 右移 n 位:rotate(1)
适合:
- 队列 FIFO
- 栈 LIFO
- 滑动窗口
统计字符频率:
from collections import Counter
c = Counter("aabbbbccd")
print(c)
输出:
Counter({'b': 4, 'a': 2, 'c': 2, 'd': 1})
其他方法:
c.most_common(2)
并集 + 交集操作:
Counter("abbc") & Counter("abccc") # 交集
Counter("abbc") | Counter("abccc") # 并集
无需检查 key 是否存在。
from collections import defaultdict
d = defaultdict(list)
d["a"].append(1)
d["a"].append(2)
print(d)
适合:
- 分组(groupby)
- 聚合统计
- 复杂 JSON 生成
示例:按名字首字母分组:
groups = defaultdict(list)
for name in ["apple", "banana", "avocado"]:
groups[name[0]].append(name)
Python 3.7+ 的内置 dict 默认有序,但 OrderedDict 仍有强功能:
from collections import OrderedDict
od = OrderedDict([("a", 1), ("b", 2)])
od.move_to_end("a")
print(od)
od = OrderedDict()
def put(k, v):
if k in od:
od.move_to_end(k)
od[k] = v
if len(od) > 3:
od.popitem(last=False)
put("a",1)
put("b",2)
put("c",3)
put("a",4) # a 最近访问
put("d",5) # 弹出 b
应用场景:
- 多层变量作用域
- 多配置文件合并
- 逐级查找
示例:
from collections import ChainMap
defaults = {"a": 1, "b": 2}
user = {"b": 20, "c": 30}
cm = ChainMap(user, defaults)
print(cm["b"]) # 20 (来自用户)
print(cm["a"]) # 1 (来自默认)
不会创建新 dict,查询效率很高。
想继承 dict 但不想踩坑?
用 UserDict:
from collections import UserDict
class MyDict(UserDict):
def keys_upper(self):
return [k.upper() for k in self.keys()]
d = MyDict({"a": 1, "b": 2})
print(d.keys_upper())
为何不用继承内置 dict?
- 内置类型有 C 实现逻辑,不能完全重写行为
- UserDict 用 Python 实现,适合扩展
按 module 分组新闻:
groups = defaultdict(list)
for item in data:
groups[item["module"]].append(item)
统计标题出现频次:
from collections import Counter
count = Counter(item["title"] for item in data)
print(count.most_common(5))
from collections import deque
window = deque(maxlen=5)
for price in prices:
window.append(price)
print(sum(window) / len(window))
| 场景 | 建议结构 |
|---|---|
| 高频队列(FIFO) | deque |
| 文本字符频率统计 | Counter |
| 层级配置读取 | ChainMap |
| 自动分组 | defaultdict(list) |
| 轻量结构体 | namedtuple |
| 可继承容器 | UserDict |
| 简单数据缓存 | OrderedDict + LRU |