目录
defaultdict
:默认值字典Counter
:计数器deque
:双端队列namedtuple
:命名元组OrderedDict
:有序字典ChainMap
:链式字典UserDict
/UserList
/UserString
:自定义容器基类
1. defaultdict
:默认值字典
特性
- 自动处理缺失键:当访问不存在的键时,返回预定义的默认值(如
int
、list
)。 - 底层实现:继承自
dict
,通过default_factory
参数指定默认值生成函数。
实际场景
- 统计元素频率:
from collections import defaultdict words = ["apple", "banana", "apple"] word_count = defaultdict(int) for word in words:word_count[word] += 1 # 无需检查键是否存在
- 分组数据:
students = [("Alice", 90), ("Bob", 85), ("Alice", 95)] grouped = defaultdict(list) for name, score in students:grouped[name].append(score) # 自动创建列表
面试问题
- Q:
defaultdict
和普通dict
的get(key, default)
有何区别?
A:defaultdict
的默认值在键不存在时会被自动创建并存储,而get()
不会修改字典。
2. Counter
:计数器
特性
- 高效统计:快速计算可哈希对象(如字符串、列表)中元素的频率。
- 丰富接口:支持
most_common(n)
、update()
等方法。
实际场景
- 分析日志数据:统计访问量最高的 IP 地址:
from collections import Counter logs = ["192.168.1.1", "192.168.1.2", "192.168.1.1"] ip_count = Counter(logs) top_ips = ip_count.most_common(2) # [('192.168.1.1', 2), ...]
- 合并统计结果:
counter1 = Counter(a=3, b=1) counter2 = Counter(a=1, b=2) combined = counter1 + counter2 # Counter({'a':4, 'b':3})
面试问题
- Q: 如何用
Counter
找出两个字符串是否为变位词(Anagram)?
A: 比较Counter(s1) == Counter(s2)
。
3. deque
:双端队列
特性
- 高效操作:首尾插入/删除的时间复杂度为 O(1)。
- 线程安全:支持多线程环境下的高效操作。
实际场景
- 实现滑动窗口算法:
from collections import deque def sliding_window(nums, k):window = deque()for num in nums[:k]:window.append(num)yield list(window)for num in nums[k:]:window.popleft()window.append(num)yield list(window)
- 处理实时数据流:保留最近 N 条记录:
data_stream = deque(maxlen=100) # 自动丢弃旧数据
面试问题
- Q:
deque
和list
在首部插入的性能差异?
A:deque
的appendleft()
是 O(1),而list.insert(0, x)
是 O(n)。
4. namedtuple
:命名元组
特性
- 代码可读性:为元组的每个位置赋予字段名,类似轻量级类。
- 内存高效:与普通元组内存占用相同。
实际场景
- 处理数据库查询结果:
from collections import namedtuple User = namedtuple("User", ["id", "name", "email"]) row = (1, "Alice", "alice@example.com") user = User(*row) print(user.name) # "Alice"
- 替代字典存储配置:
Config = namedtuple("Config", ["host", "port"]) config = Config(host="localhost", port=8080)
面试问题
- Q: 何时使用
namedtuple
而不是普通类?
A: 当需要不可变数据、轻量级结构且无需方法时。
5. OrderedDict
:有序字典
特性
- 插入顺序保留:Python 3.7+ 后普通
dict
也支持,但OrderedDict
提供额外方法(如move_to_end
)。
实际场景
- 实现 LRU 缓存:
from collections import OrderedDict class LRUCache:def __init__(self, capacity):self.cache = OrderedDict()self.capacity = capacitydef get(self, key):if key not in self.cache:return -1self.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] = valueif len(self.cache) > self.capacity:self.cache.popitem(last=False)
面试问题
- Q: Python 3.7+ 的普通
dict
已经有序,为何还需要OrderedDict
?
A:OrderedDict
提供move_to_end()
等特有方法。
6. ChainMap
:链式字典
特性
- 多字典视图:将多个字典合并为一个逻辑视图,按顺序查找键。
实际场景
- 管理配置优先级(如默认配置 < 环境配置 < 用户配置):
from collections import ChainMap defaults = {"host": "localhost", "port": 8080} user_config = {"port": 9090} config = ChainMap(user_config, defaults) print(config["port"]) # 9090(用户配置优先)
面试问题
- Q:
ChainMap
和合并多个字典({**d1, **d2}
)有何区别?
A:ChainMap
是逻辑视图,不修改原字典;合并字典会创建新对象。
7. UserDict
/UserList
/UserString
:自定义容器基类
特性
- 安全继承:比直接继承内置类型更灵活,避免覆盖原生方法的问题。
- 封装数据:通过
self.data
属性访问底层数据。
实际场景
- 自定义字典的 JSON 序列化逻辑:
from collections import UserDict class SafeDict(UserDict):def __setitem__(self, key, value):if not isinstance(key, str):raise TypeError("Key must be a string")super().__setitem__(key, value)
面试问题
- Q: 为何推荐使用
UserDict
而不是直接继承dict
?
A: 直接继承dict
时,某些方法(如update()
)可能绕过重写的逻辑。
若有错误与不足请指出,关注DPT一起进步吧!!!