NOTE目录骨架来自菜鸟教程 Python3 数据结构章节,表述与细节对照 Python 官方文档 与相关 PEP 核对。基于 Python 3。完整出处见文末 参考。
字典 dict
Mapping Types — dict:dict 把可哈希键映射到任意对象。键几乎任意,但 list、dict 等不可哈希类型不能当键;1、1.0、True 等等价键指向同一项。
创建
empty = {}also_empty = dict()
user = {"name": "Alice", "age": 25}from_pairs = dict([("a", 1), ("b", 2)])from_zip = dict(zip(["a", "b"], [1, 2]))from_keys = dict.fromkeys(["x", "y"], 0) # 值默认为 Nonefrom_kwargs = dict(red=1, blue=2) # 键须为合法标识符注意:{} 是空 dict,不是空 set。空 set 必须写 set()(见下文)。
自 3.7 起,dict 保持插入顺序;更新已有键的值不改变该键在顺序中的位置;删除后再插入的键排到末尾。
插入、查找、删除
| 操作 | 说明 |
|---|---|
d[key] = value | 插入或更新 |
value = d[key] | 取值;键不存在 → KeyError |
del d[key] | 删除;键不存在 → KeyError |
key in d / key not in d | 成员测试(测的是键) |
len(d) | 键值对个数 |
list(d) | 键的 list(插入顺序) |
scores = {"math": 90}scores["english"] = 85scores["math"] = 95 # 更新,顺序不变print(scores["math"]) # 95del scores["english"]# print(scores["physics"]) # KeyErrorget 与 setdefault
d.get(key[, default]) — 键存在则返回值,否则返回 default(省略时为 None),不抛 KeyError:
config = {"host": "localhost"}port = config.get("port", 8080)print(port) # 8080print(config.get("host")) # localhostd.setdefault(key[, default]) — 键存在则返回值;不存在则插入 key: default 并返回 default(default 省略时为 None):
cache = {}cache.setdefault("count", 0)cache["count"] += 1print(cache) # {'count': 1}典型用途:统计词频、按 key 分组时初始化默认值。需要「缺省值为新 list」等可变对象时,更常用 collections.defaultdict(后续篇章)。
keys、values、items
三者返回视图对象(Dictionary view objects):反映 dict 当前内容,不是静态快照。
d = {"a": 1, "b": 2}print(list(d.keys())) # ['a', 'b']print(list(d.values())) # [1, 2]print(list(d.items())) # [('a', 1), ('b', 2)]
for k, v in d.items(): print(k, v)视图支持 in、len、迭代。两个 dict.values() 视图互相比永远为 False(即使来自同一 dict)——官方文档有说明。
自 3.8 起 dict 及其视图可逆:reversed(d)、reversed(d.keys()) 等按插入顺序反序。
合并(3.9+)
defaults = {"theme": "light", "lang": "zh"}user_pref = {"lang": "en"}merged = defaults | user_pref # 新 dict,右侧优先print(merged) # {'theme': 'light', 'lang': 'en'}
defaults |= user_pref # 原地更新 defaults其他常用方法(入门)
| 方法 | 作用 |
|---|---|
d.update(...) | 批量更新,覆盖已有键 |
d.pop(key[, default]) | 删除并返回值 |
d.popitem() | 删除并返回 LIFO 的 (key, value) |
d.clear() | 清空 |
d.copy() | 浅拷贝 |
完整列表见文末附录。
字典推导式(预览)
语法 {key_expr: value_expr for ... in iterable if ...},与 list 推导式类似,第 6 篇统一讲:
squares = {x: x * x for x in range(5)}print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}dict.fromkeys(iterable, value) 的 value 若用可变对象(如 []),所有键会共享同一对象;要各自独立应改用 dict 推导式(官方 fromkeys 文档说明)。
集合 set
Set Types — set, frozenset:无序、元素不重复的可哈希对象集合。用途:成员测试、去重、交并差等。
创建与去重
empty = set() # 不能写 {}tags = {"python", "blog", "python"} # {'python', 'blog'}from_list = set([1, 2, 2, 3]) # {1, 2, 3}from_str = set("hello") # {'h', 'e', 'l', 'o'}raw = [1, 2, 2, 3, 3, 3]unique = list(set(raw)) # 顺序不保证;要保序见第 6 篇 dict.fromkeys 技巧print(unique)set 不支持索引、切片;元素无固定顺序,for 迭代顺序实现相关,不要依赖。
成员与长度
s = {1, 2, 3}print(2 in s) # Trueprint(len(s)) # 3集合运算:运算符与方法
对 set ↔ set,运算符与对应方法等价;方法形式常可接受任意 iterable,运算符要求两侧为 set(官方 Note)。
| 运算符 | 方法 | 含义 |
|---|---|---|
s | t | s.union(t, ...) | 并集 |
s & t | s.intersection(t, ...) | 交集 |
s - t | s.difference(t, ...) | 差集(在 s 不在 t) |
s ^ t | s.symmetric_difference(t) | 对称差(恰在一侧) |
s <= t | s.issubset(t) | 子集 |
s >= t | s.issuperset(t) | 超集 |
s.isdisjoint(t) | 无交集为 True |
a = {1, 2, 3}b = {3, 4, 5}print(a | b) # {1, 2, 3, 4, 5}print(a & b) # {3}print(a - b) # {1, 2}print(a ^ b) # {1, 2, 4, 5}原地更新(仅 set,非 frozenset):
| 运算符 | 方法 |
|---|---|
s |= t | s.update(t, ...) |
s &= t | s.intersection_update(t, ...) |
s -= t | s.difference_update(t, ...) |
s ^= t | s.symmetric_difference_update(t) |
skills = {"python", "git"}skills |= {"docker", "python"}print(skills) # {'python', 'git', 'docker'}增删元素(可变 set)
s = {1, 2}s.add(3)s.remove(2) # 不存在 → KeyErrors.discard(99) # 不存在不报错x = s.pop() # 任意移除一项;空 set → KeyErrors.clear()set 与 frozenset 混合运算时,结果类型与左操作数一致(官方说明)。
frozenset
不可变、可哈希的集合。不能 add / remove,可作 dict 键或嵌套在 set 里:
inner = frozenset([1, 2])outer = {inner, frozenset([3])}print(inner in outer) # True
# { {1, 2} } # TypeError: set 不能作元素registry = {frozenset("ab"): "pair"}构造:frozenset()、frozenset(iterable)。支持与 set 相同的只读运算(union、intersection 等及对应运算符)。
容易踩的坑
{}是 dict,set()才是空 set。- dict 键必须可哈希 —— 数字、字符串、tuple(元素皆哈希)可以;list、dict 不行。
- set 去重不保序 —— 要保留首次出现顺序:
list(dict.fromkeys(seq))(3.7+ dict 保序),比list(set(seq))稳。 - 集合元素必须可哈希 —— 同 dict 键;要存 list 可先
tuple(...)。
附录:dict 方法全集
| 方法 / 操作 | 说明 |
|---|---|
clear() | 清空 |
copy() | 浅拷贝 |
fromkeys(iterable, value=None) | 类方法,键来自 iterable |
get(key, default=None) | 安全取值 |
items() | (key, value) 视图 |
keys() | 键视图 |
values() | 值视图 |
pop(key[, default]) | 删除并返回 |
popitem() | LIFO 弹出一项 |
setdefault(key, default=None) | 无则插入 |
update([mapping,] **kwargs) | 批量更新 |
d | other / d |= other | 合并(3.9+) |
reversed(d) | 逆序键(3.8+) |
另有:d[key]、del d[key]、key in d、len(d)、iter(d)。
附录:set / frozenset 方法全集
| 方法 | set | frozenset |
|---|---|---|
union / | | ✓ | ✓ |
intersection / & | ✓ | ✓ |
difference / - | ✓ | ✓ |
symmetric_difference / ^ | ✓ | ✓ |
copy() | ✓ | ✓ |
isdisjoint | ✓ | ✓ |
issubset / <= / < | ✓ | ✓ |
issuperset / >= / > | ✓ | ✓ |
update / |= 等原地运算 | ✓ | — |
add / remove / discard / pop / clear | ✓ | — |
另有:x in s、len(s)、for x in s。
参考
官方文档(中文版 可对照阅读):
- Mapping Types — dict — 键值操作、
get/setdefault、视图 - Dictionary view objects
- Set Types — set, frozenset — 运算符与方法
- Dictionaries — 教程示例
- Sets — 教程中的集合用法
目录来源(骨架,不以它为准改语法):
- 菜鸟教程 · 数据结构 — dict / set 章节(去重、空 set 等 tips)