Python collections 模块详解
collections 模块提供了Python内置容器的替代实现,具有更强的功能和性能优化。下面介绍其中最常用的几个类:
1. Counter(计数器)
用于统计可哈希对象的频次
from collections import Counter
# 创建Counter对象
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
word_counts = Counter(words)
print(word_counts)
# Counter({'apple': 3, 'banana': 2, 'orange': 1})
# 字符串统计
letters = Counter('abracadabra')
print(letters) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# 常用方法
print(letters.most_common(3)) # [('a', 5), ('b', 2), ('r', 2)]
print(letters['a']) # 5
print(letters['z']) # 0(不存在的键返回0)
# 更新计数器
letters.update('aaaazzz')
print(letters['a']) # 9
print(letters['z']) # 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})
2. defaultdict(默认字典)
提供默认值,避免KeyError
from collections import defaultdict
# 默认值为int(0)
d1 = defaultdict(int)
d1['a'] += 1
print(d1['a']) # 1
print(d1['b']) # 0(访问不存在的键自动创建)
# 默认值为list(空列表)
d2 = defaultdict(list)
d2['fruits'].append('apple')
d2['fruits'].append('banana')
d2['vegetables'].append('carrot')
print(d2)
# defaultdict(<class 'list'>, {'fruits': ['apple', 'banana'], 'vegetables': ['carrot']})
# 默认值为set(空集合)
d3 = defaultdict(set)
d3['tags'].add('python')
d3['tags'].add('programming')
print(d3) # defaultdict(<class 'set'>, {'tags': {'python', 'programming'}})
# 自定义默认值工厂函数
def default_value():
return 'unknown'
d4 = defaultdict(default_value)
print(d4['name']) # 'unknown'
3. deque(双端队列)
高效的双向队列
from collections import deque
# 创建双端队列
d = deque([1, 2, 3])
print(d) # deque([1, 2, 3])
# 添加元素
d.append(4) # 右侧添加
d.appendleft(0) # 左侧添加
print(d) # deque([0, 1, 2, 3, 4])
# 弹出元素
right = d.pop() # 右侧弹出
left = d.popleft() # 左侧弹出
print(f'right: {right}, left: {left}') # right: 4, left: 0
print(d) # deque([1, 2, 3])
# 旋转
d.rotate(1) # 向右旋转1位
print(d) # deque([3, 1, 2])
d.rotate(-1) # 向左旋转1位
print(d) # deque([1, 2, 3])
# 限制队列长度
limited = deque(maxlen=3)
for i in range(5):
limited.append(i)
print(limited)
# deque([0], maxlen=3)
# deque([0, 1], maxlen=3)
# deque([0, 1, 2], maxlen=3)
# deque([1, 2, 3], maxlen=3) # 自动弹出最左元素
# deque([2, 3, 4], maxlen=3)
4. OrderedDict(有序字典)
保持插入顺序的字典
from collections import OrderedDict
# 创建有序字典
od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
print(list(od.keys())) # ['z', 'y', 'x']
# 移动元素到末尾
od.move_to_end('z')
print(list(od.keys())) # ['y', 'x', 'z']
# 移动元素到开头
od.move_to_end('z', last=False)
print(list(od.keys())) # ['z', 'y', 'x']
# 弹出元素
last_item = od.popitem() # 默认弹出最后一个
first_item = od.popitem(last=False) # 弹出第一个
print(last_item, first_item) # ('x', 2) ('z', 1)
5. namedtuple(命名元组)
创建带字段名的元组
from collections import namedtuple
# 定义命名元组类型
Point = namedtuple('Point', ['x', 'y'])
Person = namedtuple('Person', 'name age gender')
# 创建实例
p = Point(10, 20)
person = Person('Alice', 25, 'F')
print(p.x, p.y) # 10 20
print(person.name, person.age) # Alice 25
# 索引访问仍可用
print(p[0]) # 10
# 转换为字典
print(p._asdict()) # {'x': 10, 'y': 20}
# 替换字段值
p2 = p._replace(x=100)
print(p2) # Point(x=100, y=20)
6. ChainMap(链式映射)
合并多个字典
from collections import ChainMap
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
dict3 = {'d': 5}
# 创建链式映射
chain = ChainMap(dict1, dict2, dict3)
# 查找:按顺序从前往后查找
print(chain['a']) # 1(来自dict1)
print(chain['b']) # 2(来自dict1,不会继续查找dict2)
print(chain['c']) # 4(来自dict2)
print(chain['d']) # 5(来自dict3)
# 更新
chain['b'] = 100 # 只会更新第一个映射(dict1)
print(dict1) # {'a': 1, 'b': 100}
# 添加新映射
new_chain = chain.new_child({'e': 6})
print(new_chain['e']) # 6
# 获取所有键
print(list(chain.keys())) # ['a', 'b', 'd', 'c']
7. 实际应用示例
from collections import defaultdict, Counter
import json
# 示例1:统计学生成绩
scores = [
('Alice', 85), ('Bob', 90), ('Alice', 92),
('Charlie', 78), ('Bob', 88), ('Alice', 95)
]
# 使用defaultdict自动创建列表
score_dict = defaultdict(list)
for name, score in scores:
score_dict[name].append(score)
for name, score_list in score_dict.items():
avg = sum(score_list) / len(score_list)
print(f'{name}: {score_list}, 平均分: {avg:.1f}')
# 示例2:实现简单缓存
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
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)
# 使用缓存
cache = LRUCache(2)
cache.put('a', 1)
cache.put('b', 2)
print(cache.get('a')) # 1
cache.put('c', 3) # 超出容量,删除最旧的'b'
print(cache.get('b')) # -1(已被删除)
总结
collections 模块提供了强大的数据结构扩展:
-
Counter:快速统计频次
-
defaultdict:避免KeyError,自动提供默认值
-
deque:高效的双端队列,适合队列和栈操作
-
OrderedDict:保持插入顺序的字典
-
namedtuple:创建更易读的元组
-
ChainMap:合并多个字典的视图
这些工具能显著提升代码的简洁性和性能,是Python编程中不可或缺的工具。
浙公网安备 33010602011771号