python的 collections 模块提供了多种高性能的容器数据类型,用于替代或增强内置的 list、dict、tuple 等,以解决特定场景下的编程需求,提升代码效率和可读性 。
核心数据结构及常用用法
| 数据结构 | 主要功能 | 典型应用场景 |
|---|---|---|
namedtuple | 创建带有字段名的元组子类 | 定义轻量级、不可变的数据对象,如坐标点、数据库记录 |
deque | 高效的双端队列 | 实现队列、栈,或需要频繁在两端添加/删除元素的场景 |
counter | 计数器,用于统计可哈希对象 | 统计词频、元素出现次数,找 top n 元素 |
defaultdict | 带默认工厂的字典 | 分组、归类数据,避免键不存在时的 keyerror 检查 |
ordereddict | 保持元素插入顺序的字典 | 需要记住元素插入顺序或实现 lru 缓存 |
chainmap | 将多个映射链接为单个视图 | 管理多层配置(如默认配置、用户配置、环境配置) |
1. namedtuple:命名元组
用于创建具有命名字段的元组子类,使代码更易读。
from collections import namedtuple
# 定义一个表示二维坐标点的命名元组
point = namedtuple('point', ['x', 'y'])
p = point(10, y=20)
print(p.x, p.y) # 输出: 10 20print(p[0] + p[1]) # 输出: 30,仍支持索引访问
# 定义一个表示用户信息的命名元组
user = namedtuple('user', 'name age city')
user1 = user('alice', 30, 'beijing')
print(f"{user1.name} lives in {user1.city}") # 输出: alice lives in beijing
2. deque:双端队列
支持从两端快速添加和弹出元素,线程安全。
from collections import deque
# 初始化一个双端队列
d = deque([1, 2, 3])
d.append(4) # 右侧添加元素 -> deque([1, 2, 3, 4])
d.appendleft(0) # 左侧添加元素 -> deque([0, 1, 2, 3, 4])
print(d.pop()) # 输出: 4,从右侧弹出
print(d.popleft()) # 输出: 0,从左侧弹出
# 创建固定长度的队列,当队列满时,添加新元素会挤出另一端元素
rolling_window = deque(maxlen=3)
for i in range(5):
rolling_window.append(i)
print(rolling_window) # 输出: deque([0], maxlen=3) -> deque([0,1], maxlen=3) -> ... -> deque([2,3,4], maxlen=3)
3. counter:计数器
用于统计可迭代对象中元素的出现次数。
from collections import counter
# 统计列表元素频率
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
word_counts = counter(words)
print(word_counts) # 输出: counter({'apple': 3, 'banana': 2, 'orange': 1})
# 直接统计字符串字符
char_counter = counter('abracadabra')
print(char_counter.most_common(3)) # 输出: [('a', 5), ('b', 2), ('r', 2)],出现频率最高的3个# 计数器支持数学运算
c1 = counter(a=3, b=1)
c2 = counter(a=1, b=2)
print(c1 + c2) # 输出: counter({'a': 4, 'b': 3})
print(c1 - c2) # 输出: counter({'a': 2}),只保留正数计数
4. defaultdict:默认字典
在创建字典时提供一个默认值工厂函数,当访问不存在的键时,会自动生成默认值。
from collections import defaultdict
# 值为列表的默认字典,常用于分组
group_by_length = defaultdict(list)
words = ['apple', 'bat', 'bar', 'atom', 'book']
for word in words:
group_by_length[len(word)].append(word)
print(dict(group_by_length)) # 输出: {5: ['apple'], 3: ['bat', 'bar', 'atom'], 4: ['book']}
# 值为整数的默认字典,用于计数(类似counter的简单实现)
count_dict = defaultdict(int)
for char in 'programming':
count_dict[char] += 1
print(dict(count_dict)) # 输出: {'p':1, 'r':2, 'o':1, ...}
# 使用lambda设置复杂的默认值default_with_lambda = defaultdict(lambda: '未知')
default_with_lambda['name'] = 'alice'
print(default_with_lambda['age']) # 输出: '未知',而不是引发keyerror
5. ordereddict:有序字典
记住键值对插入的顺序(python 3.7+ 的普通 dict 也已保证插入顺序,但 ordereddict 在相等性比较和重新排序方法上仍有优势)。
from collections import ordereddict
# 创建有序字典
od = ordereddict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
print(list(od.keys())) # 输出: ['z', 'y', 'x'],保持插入顺序
# 移动元素到末尾(可用于实现lru缓存)
od.move_to_end('z')
print(list(od.keys())) # 输出: ['y', 'x', 'z']
# 相等性比较:ordereddict会考虑顺序
od1 = ordereddict([('a', 1), ('b', 2)])
od2 = ordereddict([('b', 2), ('a', 1)])
print(od1 == od2) # 输出: false,因为顺序不同
6. chainmap:链式映射
将多个字典或其他映射组合成一个单一的视图,查找时按顺序搜索底层映射。
from collections import chainmap
# 模拟配置优先级:命令行参数 > 用户配置 > 默认配置
defaults = {'theme': 'light', 'language': 'en'}
user_config = {'theme': 'dark'}
cli_args = {}
# 创建链式映射,查找顺序从左到右
config = chainmap(cli_args, user_config, defaults)
print(config['theme']) # 输出: 'dark',优先使用user_config中的值
print(config['language'])# 输出: 'en',user_config中没有,回退到defaults
# 新增更新只影响第一个映射
config['language'] = 'zh'
print(user_config) # 输出: {'theme': 'dark', 'language': 'zh'}
进阶与性能考量
collections 模块还提供了 userdict、userlist、userstring 等类,用于方便地创建自定义的字典、列表、字符串子类 。在性能上,deque 在两端操作(appendleft/popleft)上比 list 的 insert(0, item)/pop(0) 快得多(o(1) vs o(n))。counter 和 defaultdict 在统计和分组任务中,也比手动使用普通 dict 并检查键是否存在更简洁高效 。
到此这篇关于python基础指南之collections模块中高效容器对比与选择详解的文章就介绍到这了,更多相关python collections容器选择内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论