5. 数据结构
list/tuple/set/dict API、推导式与嵌套、del、用 enumerate/zip 写循环——对齐 Map/Set/数组心智并标出可变与哈希约束。
5.1 列表 list
常用方法(速记)
| 方法 | 作用 |
|---|---|
append(x) | 尾部加一个元素 |
extend(iter) | 追加一系列元素 |
insert(i, x) | 在索引前插入 |
remove(x) | 删第一个等于 x 的项 |
pop([i]) | 弹出并返回(默认末尾) |
clear() | 清空 |
index(x) / count(x) | 查找 / 计数 |
sort() / reverse() | 原地排序 / 反转 |
copy() | 浅拷贝 |
当作栈 / 队列
- 栈:
append+pop()。 - 队列:列表左侧弹出是 O(n);高频双端队列用
collections.deque。
stack: list[int] = [1, 2]
stack.append(3)
stack.pop() # 3
from collections import deque
q: deque[int] = deque([1, 2])
q.append(3)
q.popleft() # 1列表推导式
squares = [x**2 for x in range(5)]
# 等价于带 filter 的 map
evens = [x * 2 for x in [-1, 0, 1] if x >= 0]
nested = [[1, 2], [3, 4]]
flat = [num for row in nested for num in row]
matrix = [[1, 2], [3, 4], [5, 6]]
cols = [[row[i] for row in matrix] for i in range(2)]
# 更常见:list(zip(*matrix)) → [(1, 3, 5), (2, 4, 6)]5.2 del 语句
按索引 / 切片删除,不产生值(和 pop 不同)。
a = [1, 2, 3, 4]
del a[0] # [2, 3, 4]
del a[1:3] # [2]
del a[:] # []5.3 元组 tuple
- 不可变序列;内容全可哈希时,可当 dict 键 或 set 元素。
- 单元素元组:
(1,),逗号不能省。 - 解构:
x, y, z = point;*rest吃剩余。
page = ("https://example.com", 200, 1024)
url, status, size = page
head, *tail = (1, 2, 3, 4)
print(head, tail) # 1 [2, 3, 4]5.4 集合 set
- 无序、元素唯一;
{}建的是空字典,空集合必须set()。 - 运算:
- | & ^(差 / 并 / 交 / 对称差)。
seen: set[str] = set()
for token in ["a", "b", "a"]:
seen.add(token)
print(seen) # {'a', 'b'}
old = {1, 2, 3}
new = {2, 3, 4}
print(new - old) # {4} 新增
print(old - new) # {1} 删除
print(old & new) # {2, 3} 交集5.5 字典 dict(3.7+ 保插入序)
- 键必须 hashable;不要用
list/dict当键。 - 合并字典(3.9+):
|与|=。
base = {"a": 1, "b": 2}
overlay = {"b": 99, "c": 3}
merged = base | overlay
print(merged) # {'a': 1, 'b': 99, 'c': 3}
# setdefault / defaultdict:统计词频时很省事
counts: dict[str, int] = {}
for word in ["a", "b", "a"]:
counts[word] = counts.get(word, 0) + 1.keys() / .values() / .items() 是动态视图:
d = {"k": 1}
view = d.keys()
d["k"] = 2
print(list(view)) # ['k'],值通过 items() 才能看到新 value5.6 循环技巧
knights = {"gallahad": "the pure", "robin": "the brave"}
for k, v in knights.items():
print(k, v)
for i, v in enumerate(["tic", "tac", "toe"]):
print(i, v)
qs = ["When", "What"]
ans = ["Now", "ever"]
for q, a in zip(qs, ans):
print(f"What is {q!r}? {a!r}.")
# zip 以最短序列为准;需要补齐看 itertools.zip_longestsorted(iterable)返回新 list;list.sort()原地排序。- 去重保序(3.7+):
list(dict.fromkeys(items))。
5.7 比较与布尔
in/not in;作用于 dict 时检测键。and/or:短路,返回值是操作数本身:
def pick(flags: dict[str, bool]) -> str:
# 用 or 链提供默认值,像 TS 的 a ?? b 但要小心假值
return flags.get("theme") or "light"
print(pick({"theme": ""})) # 'light',因为 '' 为假5.8 速记:选型
| 需要 | 用 |
|---|---|
| 有序可变序列 | list |
| 固定记录 / 可哈希复合键 | tuple |
| 唯一成员 / 集合论 | set |
| 键值映射 | dict |
权威延伸:5. Data Structures