1. collections 模块是什么? #
collections 是 Python 内置的容器扩展包,提供了比 dict、list、set、tuple 更贴合特定场景的数据结构,比如计数器、队列、命名元组等。它无需额外安装,是写脚本、处理数据时提升效率的“标准工具箱”。
2. 如何开始使用? #
collections 随 Python 一起发布,因此 Windows 与 macOS 不需要任何安装命令。只需 import collections(或直接导入需要的类型)即可。下面的脚本展示了如何检查模块版本并验证可用性:
# 说明:导入 collections 模块以检查可用性
import collections
if __name__ == "__main__":
# 说明:输出模块所在的物理路径
print(f"collections 模块所在路径:{collections.__file__}")
# 说明:展示模块内的一个示例类型
print(f"默认字典类型:{collections.defaultdict}")3. 核心数据类型一览 #
本章分别介绍最常用的六种容器,并配套可独立运行的 Python 脚本,帮助你立即上手。
3.1 Counter:统计出现次数 #
Counter 适合统计列表、字符串或其他可哈希对象的频率。
# 说明:导入 Counter 用于统计元素出现次数
from collections import Counter
def main() -> None:
# 说明:准备一个包含重复单词的列表
words = ["apple", "banana", "apple", "orange", "banana", "apple"]
# 说明:统计列表中每个单词出现次数
word_counter = Counter(words)
print("词频:", word_counter)
# 说明:直接对字符串执行统计
char_counter = Counter("programming")
print("字符频率:", char_counter)
# 说明:获取出现次数最多的两个单词
print("出现次数最多的 2 个词:", word_counter.most_common(2))
# 说明:演示 Counter 之间的加法合并
merged = Counter(["a", "b", "c"]) + Counter(["b", "c", "d"])
print("合并后的计数器:", merged)
if __name__ == "__main__":
main()3.2 defaultdict:带默认值的字典 #
defaultdict 可以为缺失的 key 自动创建默认值,避免 KeyError。
# 说明:导入 defaultdict 以设置自动默认值
from collections import defaultdict
def main() -> None:
# 说明:创建以 list 为默认值的字典
list_dict = defaultdict(list)
list_dict["fruits"].append("apple")
list_dict["fruits"].append("banana")
print("列表默认值示例:", list_dict)
# 说明:创建以 int 为默认值的计数字典
count_dict = defaultdict(int)
for word in ["apple", "banana", "apple", "orange"]:
count_dict[word] += 1
print("整数默认值示例:", count_dict)
# 说明:定义自定义默认值函数
def fallback() -> str:
return "未知"
# 说明:使用自定义函数作为默认值
custom_dict = defaultdict(fallback)
print("自定义默认值:", custom_dict["name"])
if __name__ == "__main__":
main()3.3 deque:双端队列 #
deque 具备 O(1) 的两端插入/删除性能,适合实现队列、栈或滑动窗口。
# 说明:导入 deque 用于构建双端队列
from collections import deque
def main() -> None:
# 说明:初始化队列并从右端、左端分别添加
dq = deque(["b", "c", "d"])
dq.append("e")
dq.appendleft("a")
print("添加元素后:", dq)
# 说明:分别从右侧和左侧弹出元素
right = dq.pop()
left = dq.popleft()
print("弹出元素:", left, right)
print("当前队列:", dq)
# 说明:扩展队列并旋转以模拟窗口移动
dq.extend(["e", "f"])
dq.extendleft(["z"])
dq.rotate(2)
print("扩展并旋转后的队列:", dq)
if __name__ == "__main__":
main()3.4 namedtuple:带字段名的元组 #
namedtuple 提供“字段名 + 元组”的双重便利,适用于轻量数据结构。
# 说明:导入 namedtuple 用于创建带字段名的元组
from collections import namedtuple
def main() -> None:
# 说明:定义两个命名元组类型
Point = namedtuple("Point", ["x", "y"])
Person = namedtuple("Person", "name age city")
# 说明:创建命名元组实例
p1 = Point(10, 20)
person = Person("Alice", 25, "Beijing")
# 说明:通过字段名访问各属性
print("坐标:", p1.x, p1.y)
print("人物信息:", person.name, person.age, person.city)
print("转换为字典:", person._asdict())
if __name__ == "__main__":
main()3.5 OrderedDict:有序字典 #
在需要精确控制插入顺序或移动元素时,OrderedDict 仍然有用。
# 说明:导入 OrderedDict 以保持插入顺序
from collections import OrderedDict
def main() -> None:
# 说明:按特定顺序插入键值
od = OrderedDict()
od["z"] = 1
od["a"] = 2
od["c"] = 3
print("初始顺序:", od)
# 说明:把指定键移动到末尾
od.move_to_end("z")
print("移动 z 到末尾:", od)
# 说明:弹出键 a 以及最后一个键
od.pop("a")
last_key, last_value = od.popitem()
print("弹出元素后:", od, "| 最后弹出:", (last_key, last_value))
if __name__ == "__main__":
main()3.6 ChainMap:链接多个字典 #
ChainMap 提供“多层字典合并视图”,常用于配置合并、作用域查找。
# 说明:导入 ChainMap 用于合并多层配置
from collections import ChainMap
def main() -> None:
# 说明:依次准备默认、环境、用户配置
defaults = {"theme": "light", "lang": "zh"}
env = {"lang": "en"}
user = {"theme": "dark"}
# 说明:创建链式映射以统一读取
settings = ChainMap(user, env, defaults)
print("当前配置:", dict(settings))
# 说明:更新配置将作用于第一个映射
settings["lang"] = "jp"
print("更新后的配置:", dict(settings))
if __name__ == "__main__":
main()4. 实战案例 #
掌握基本类型后,可以把它们用于更贴近工作/学习的场景。
4.1 文本词频统计 #
# 说明:导入 Counter 和正则工具统计词频
from collections import Counter
import re
def main() -> None:
# 说明:将文本转换为小写并切分为单词
text = "hello world hello python world python python"
words = re.findall(r"\w+", text.lower())
# 说明:统计每个单词出现次数
freq = Counter(words)
print("最高频词:", freq.most_common(3))
if __name__ == "__main__":
main()4.2 构建树状数据 #
# 说明:导入 defaultdict 构建无限深度的树结构
from collections import defaultdict
def tree():
# 说明:返回自身类型作为默认值,实现自动嵌套
return defaultdict(tree)
def main() -> None:
# 说明:创建模拟文件系统并写入示例数据
file_system = tree()
file_system["home"]["user"]["documents"]["file.txt"] = "content"
file_system["home"]["user"]["downloads"]["app.zip"] = "data"
print("读取文件内容:", file_system["home"]["user"]["documents"]["file.txt"])
if __name__ == "__main__":
main()4.3 最近最少使用缓存(LRU) #
# 说明:基于 OrderedDict 实现简单 LRU 缓存
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity: int):
# 说明:使用 OrderedDict 保存缓存项
self.cache = OrderedDict()
self.capacity = capacity
def get(self, key):
# 说明:命中后将元素移动到队尾表示最近使用
if key not in self.cache:
return -1
self.cache.move_to_end(key)
return self.cache[key]
def put(self, key, value):
# 说明:更新或添加键,并移动到队尾
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
# 说明:超出容量时弹出最旧的数据
if len(self.cache) > self.capacity:
self.cache.popitem(last=False)
def main() -> None:
# 说明:创建容量为 2 的缓存并测试行为
cache = LRUCache(2)
cache.put(1, "A")
cache.put(2, "B")
print(cache.get(1))
cache.put(3, "C")
print(cache.get(2))
if __name__ == "__main__":
main()5. 总结与对比 #
| 数据类型 | 主要用途 | 上手难度 | 适用场景 |
|---|---|---|---|
| Counter | 统计元素频率 | ★ | 词频、库存统计 |
| defaultdict | 缺省值字典 | ★ | 数据归类、计数 |
| deque | 双端队列 | ★★ | 队列/栈、滑动窗口 |
| namedtuple | 轻量数据结构 | ★★ | 坐标、记录对象 |
| OrderedDict | 有序字典 | ★★ | LRU 缓存、顺序控制 |
| ChainMap | 多配置合并 | ★★ | 配置覆盖、作用域 |