Python 虽然没有像 C++ STL 那样严格划分「容器」的概念,但提供了功能完全对标 C++ 容器的内置数据结构和标准库模块,覆盖序列、关联容器、无序关联容器等核心场景。以下是详细的对标对比和使用示例,方便你从 C++ 快速过渡到 Python:
一、核心容器对标表(C++ → Python)
| C++ 容器 | Python 对应结构 | 核心特性/用途 |
|---|---|---|
vector |
list / array(数组模块) |
动态数组,随机访问、尾部增删高效 |
string |
str + bytearray |
字符串(不可变)/ 可变字节串 |
deque |
collections.deque |
双端队列,头尾增删 O(1) |
stack |
collections.deque(模拟) |
栈(用 append/pop 实现) |
queue |
collections.deque(模拟) |
队列(用 append/popleft 实现) |
set |
set / frozenset |
无序不重复集合,集合运算(交并差) |
unordered_set |
set(底层哈希实现) |
哈希集合,查找/增删 O(1) |
map |
dict(字典) |
有序键值对(3.7+默认有序) |
unordered_map |
dict(底层哈希实现) |
哈希键值对,查找/增删 O(1) |
multiset |
collections.Counter / 自定义 |
可重复集合(计数场景) |
multimap |
defaultdict(list) |
一键多值映射 |
priority_queue |
heapq 模块 |
优先队列(小顶堆,可模拟大顶堆) |
二、关键容器详细对比(附示例)
1. 动态数组:C++ vector → Python list/array
- Python
list:功能最全的动态数组,支持任意类型元素,对标vector<any>; - Python
array.array:仅存储同类型数值(如 int/float),更接近 C++vector<int>,内存更紧凑。
python
# 对标 C++ vector<int>
# 方式1:list(通用,推荐)
vec = [1, 2, 3, 4]
vec.append(5) # 尾部添加(push_back)
vec.pop() # 尾部删除(pop_back)
vec[0] = 10 # 随机访问([])
print(vec[2]) # 3(O(1) 访问)
# 方式2:array(仅数值,内存高效)
import array
arr = array.array('i', [1,2,3]) # 'i'表示int类型
arr.append(4)
print(arr[1]) # 2
2. 双端队列:C++ deque → Python collections.deque
C++ deque 对标 Python deque,头尾增删都是 O(1),适合实现栈/队列:
python
from collections import deque
# 模拟队列(FIFO)
q = deque([1,2,3])
q.append(4) # 队尾加(push_back)
q.popleft() # 队头删(pop_front)→ 返回1
print(q) # deque([2,3,4])
# 模拟栈(LIFO)
stack = deque()
stack.append(1) # 压栈
stack.append(2)
stack.pop() # 弹栈 → 返回2
3. 集合:C++ set/unordered_set → Python set
- Python
set底层是哈希表,直接对标 C++unordered_set(查找/增删 O(1)); - 若需有序集合,用
bisect模块模拟 C++set(红黑树有序特性)。
python
# 对标 unordered_set
s = {1,2,3,2} # 自动去重 → {1,2,3}
s.add(4) # 插入(insert)
s.remove(2) # 删除(erase),不存在报错
s.discard(5) # 删除,不存在不报错
print(3 in s) # True(O(1) 查找)
# 集合运算(交并差,C++需调用算法,Python直接支持)
s1 = {1,2,3}
s2 = {3,4,5}
print(s1 & s2) # 交集 {3}
print(s1 | s2) # 并集 {1,2,3,4,5}
print(s1 - s2) # 差集 {1,2}
# 模拟有序set(C++ set)
import bisect
ordered_set = []
bisect.insort(ordered_set, 3)
bisect.insort(ordered_set, 1)
bisect.insort(ordered_set, 2)
print(ordered_set) # [1,2,3](始终有序)
4. 键值对:C++ map/unordered_map → Python dict
- Python 3.7+ 中
dict默认按插入顺序排列,同时对标 C++map(有序)和unordered_map(哈希); - 一键多值(
multimap)用defaultdict(list)实现。
python
# 对标 unordered_map(哈希)/ map(有序)
d = {"name": "小明", "age": 18}
d["score"] = 90 # 插入/修改([])
print(d["name"]) # 查找(O(1))
print(d.get("gender", "未知")) # 安全查找,避免KeyError
# 遍历键值对(对标 map::iterator)
for k, v in d.items():
print(f"{k}: {v}")
# 对标 multimap(一键多值)
from collections import defaultdict
multi_map = defaultdict(list)
multi_map["fruit"].append("apple")
multi_map["fruit"].append("banana")
print(multi_map["fruit"]) # ["apple", "banana"]
5. 优先队列:C++ priority_queue → Python heapq
Python heapq 实现小顶堆,通过「取负数」模拟大顶堆(对标 C++ priority_queue<int>):
python
import heapq
# 小顶堆(默认,对标 priority_queue<int, vector<int>, greater<int>>)
min_heap = []
heapq.heappush(min_heap, 3)
heapq.heappush(min_heap, 1)
heapq.heappush(min_heap, 2)
print(heapq.heappop(min_heap)) # 1
# 大顶堆(对标 priority_queue<int>)
max_heap = []
heapq.heappush(max_heap, -3) # 存入负数
heapq.heappush(max_heap, -1)
heapq.heappush(max_heap, -2)
print(-heapq.heappop(max_heap)) # 3(取出后取反)
6. 可重复集合:C++ multiset → Python Counter
C++ multiset 用于元素可重复的场景,Python 用 collections.Counter 实现(计数+去重):
python
from collections import Counter
# 对标 multiset
ms = Counter([1,2,1,3,2,1])
print(ms[1]) # 3(1出现3次)
ms[1] -= 1 # 减少计数
print(ms[1]) # 2
ms.pop(1) # 删除键1
print(ms) # Counter({2:2, 3:1})
三、核心差异总结
| 特性 | C++ 容器 | Python 容器 |
|---|---|---|
| 类型限制 | 强类型(如 vector) | 弱类型(list 可存任意类型) |
| 内存控制 | 手动管理(resize/reserve) | 自动扩容,无需手动管理 |
| 有序性 | set/map 有序,unordered_* 无序 | dict(3.7+有序)、set 无序,bisect 模拟有序 |
| 线程安全 | 需手动加锁 | 无原生线程安全,需手动控制 |
| 迭代器 | 显式迭代器(iterator) | 隐式迭代(for 循环直接遍历) |
四、算法比赛选型建议
- 动态数组:优先用
list(通用),超大数值数组用array节省内存; - 队列/栈:必用
deque(list头删是 O(n),效率低); - 哈希查找/计数:
dict/set/defaultdict全覆盖,比 C++ 写法更简洁; - 优先队列:
heapq模块(注意小顶堆→大顶堆的转换); - 有序集合:
bisect模块(算法比赛中替代 C++set)。
Python 容器虽然语法和 C++ 不同,但功能完全覆盖,且写法更简洁(无需手动管理内存、迭代器),算法比赛中只需掌握上述对应关系,就能快速替换 C++ 容器的用法。