collections库相关知识

博客介绍了Python中collections这一容器数据类型,collections在Python编程里可用于高效处理数据,是信息技术领域中Python开发的重要内容。
`collections` 是 Python 标准中一个非常强大且常用的模块,它提供了许多**高性能、开箱即用的容器数据类型**,扩展了内置的 `list`、`dict`、`set`、`tuple` 等基础类型的功能。 --- ## 📚 一、`collections` 模块的核心类 | 类名 | 用途 | |------|------| | `defaultdict` | 带默认值的字典,避免 KeyError | | `Counter` | 计数器,统计元素出现次数 | | `deque` | 双端队列,支持高效头尾操作 | | `namedtuple` | 命名元组,带字段名的不可变结构 | | `OrderedDict` | 有序字典,保持插入顺序(Python < 3.7) | | `ChainMap` | 多个字典的逻辑合并 | | `UserDict` / `UserList` / `UserString` | 可继承的基础容器类 | 下面我们逐一详解,并附上实用代码示例。 --- ## 1. `defaultdict` —— 自动初始化的字典 ✅ ### 🔍 作用 当访问不存在的 key 时,自动创建一个默认类型的 value。 ### 💡 场景 - 构建 `dict[int, list]`、`dict[str, set]` 等嵌套结构 - 避免写 `if key not in d: d[key] = []` ### ✅ 示例 ```python from collections import defaultdict # 创建一个 value 为列表的字典 d = defaultdict(list) d['a'].append(1) d['a'].append(2) d['b'].append(3) print(d) # defaultdict(<class 'list'>, {'a': [1, 2], 'b': [3]}) # 统计字符频次 freq = defaultdict(int) for c in "hello": freq[c] += 1 print(freq) # {'h': 1, 'e': 1, 'l': 2, 'o': 1} ``` > ⚠️ 注意:`defaultdict` 不会为未访问的 key 创建条目,只有当你“读取”某个 key 时才生成。 --- ## 2. `Counter` —— 计数神器 🔢 ### 🔍 作用 统计可哈希对象的出现次数。 ### ✅ 示例 ```python from collections import Counter # 统计字符 c = Counter("hello") print(c) # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) # 统计单词 words = ["apple", "banana", "apple", "cherry", "banana", "apple"] c = Counter(words) print(c.most_common(2)) # [('apple', 3), ('banana', 2)] # 支持加减运算 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}) ``` ### 🧩 实用技巧 ```python # 找出两个字符串是否是字母异位词(anagram) def is_anagram(s1, s2): return Counter(s1) == Counter(s2) print(is_anagram("listen", "silent")) # True ``` --- ## 3. `deque` —— 双端队列 🔄 ### 🔍 作用 在列表两端进行 **O(1)** 时间复杂度的添加/删除操作。 ### 💡 对比 `list` | 操作 | `list` | `deque` | |------|--------|--------| | `append()` | O(1) amortized | O(1) | | `appendleft()` | ❌ 无 | O(1) ✅ | | `pop(0)` 或 `pop_left()` | O(n) | O(1) ✅ | | `insert(0, x)` | O(n) | O(1) for `appendleft` | ### ✅ 示例 ```python from collections import deque dq = deque([1, 2, 3]) dq.appendleft(0) dq.append(4) dq.popleft() print(dq) # deque([1, 2, 3, 4]) # 限制长度(滑动窗口) fixed_dq = deque(maxlen=3) for i in range(5): fixed_dq.append(i) print(fixed_dq) # deque([2, 3, 4], maxlen=3) ``` ### 🧩 应用场景 - BFS 层序遍历 - 滑动窗口最大值 - 实现缓冲区、历史记录等 --- ## 4. `namedtuple` —— 命名元组 🏷️ ### 🔍 作用 创建轻量级、不可变的类式结构,但比 class 更快更省内存。 ### ✅ 示例 ```python from collections import namedtuple # 定义一种“点”类型 Point = namedtuple('Point', ['x', 'y']) p = Point(10, 20) print(p.x, p.y) # 10 20 print(p) # Point(x=10, y=20) print(p._asdict()) # OrderedDict([('x', 10), ('y', 20)]) # 定义一个数据包结构 Packet = namedtuple('Packet', ['source', 'destination', 'timestamp']) pkt = Packet(source=1, destination=2, timestamp=100) print(pkt.destination) # 2 ``` > ✅ 优势:可读性强、支持索引和属性访问、线程安全、序列化方便 --- ## 5. `OrderedDict` —— 有序字典 📜 ### 🔍 作用 保持键值对的插入顺序。 > ⚠️ Python 3.7+ 中普通 `dict` 已经默认保持插入顺序,所以 `OrderedDict` 使用减少。 ### ✅ 特有功能 ```python from collections import OrderedDict od = OrderedDict() od['a'] = 1 od['b'] = 2 od['c'] = 3 od.move_to_end('a') # 移到最后 print(od) # OrderedDict([('b', 2), ('c', 3), ('a', 1)]) # 比较时考虑顺序 od1 = OrderedDict([('a', 1), ('b', 2)]) od2 = OrderedDict([('b', 2), ('a', 1)]) print(od1 == od2) # False(普通 dict 相等) ``` --- ## 6. `ChainMap` —— 多字典视图 🔗 ### 🔍 作用 将多个字典组合成一个逻辑上的整体,查找时逐个搜索。 ### ✅ 示例 ```python from collections import ChainMap default_config = {'host': 'localhost', 'port': 8080} user_config = {'port': 9000} combined = ChainMap(user_config, default_config) print(combined['host']) # localhost(从 default_config 获取) print(combined['port']) # 9000(优先 user_config) ``` ### 🧩 应用场景 - 配置管理(用户配置覆盖默认配置) - 变量作用域链(如局部变量 → 全局变量) --- ## 7. `UserDict`, `UserList`, `UserString` —— 可继承容器 🛠️ 当你想自定义容器行为时使用。 ### ✅ 示例:带长度限制的字典 ```python from collections import UserDict class LimitedDict(UserDict): def __init__(self, max_len=5): super().__init__() self.max_len = max_len def __setitem__(self, key, value): if len(self.data) >= self.max_len: # 删除最老的一项(基于插入顺序) old_key = next(iter(self.data)) del self.data[old_key] super().__setitem__(key, value) d = LimitedDict(max_len=3) for i in range(5): d[f'key{i}'] = i print(d) # {'key2': 2, 'key3': 3, 'key4': 4} ``` --- ## 🎯 总结:各类型适用场景一览 | 类型 | 推荐使用场景 | |------|-------------| | `defaultdict` | 构建分组映射、邻接表、频率统计 | | `Counter` | 统计频次、比较集合、找众数 | | `deque` | 高频头尾操作、BFS、滑动窗口 | | `namedtuple` | 表示简单数据结构(如坐标、记录) | | `OrderedDict` | 需要精确控制顺序或做 LRU 缓存 | | `ChainMap` | 多层配置合并、作用域链 | | `UserDict/List` | 自定义容器逻辑 | --- ## 🧪 小练习:综合应用 用 `collections` 实现一个简单的**包路由器统计器**: ```python from collections import defaultdict, Counter, deque class SimpleRouter: def __init__(self): self.packets = deque() self.by_dest = defaultdict(list) self.src_count = Counter() def add_packet(self, src, dest, ts): packet = (src, dest, ts) self.packets.append(packet) self.by_dest[dest].append(ts) self.src_count[src] += 1 def get_recent_dest_packets(self, dest, last_n=5): return self.by_dest[dest][-last_n:] def top_sources(self, n=3): return self.src_count.most_common(n) # 使用示例 r = SimpleRouter() r.add_packet(1, 2, 100) r.add_packet(1, 3, 101) r.add_packet(2, 2, 102) r.add_packet(3, 2, 103) print(r.get_recent_dest_packets(2)) # [100, 102, 103] print(r.top_sources()) # [(1, 2), (2, 1), (3, 1)] ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值