Python的 collections 模块提供了多种高性能的容器数据类型,用于替代或增强内置的 listdicttuple 等,以解决特定场景下的编程需求,提升代码效率和可读性 。

核心数据结构及常用用法

数据结构 主要功能 典型应用场景
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 模块还提供了 UserDictUserListUserString 等类,用于方便地创建自定义的字典、列表、字符串子类 。在性能上,deque 在两端操作(appendleft/popleft)上比 listinsert(0, item)/pop(0) 快得多(O(1) vs O(n))。Counterdefaultdict 在统计和分组任务中,也比手动使用普通 dict 并检查键是否存在更简洁高效 。

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章

1 2 3 4 5