1477 字
7 分钟
Python 札记 (5)
2026-08-28
NOTE

目录骨架来自菜鸟教程 Python3 数据结构章节,表述与细节对照 Python 官方文档 与相关 PEP 核对。基于 Python 3。完整出处见文末 参考

字典 dict#

Mapping Types — dictdict可哈希键映射到任意对象。键几乎任意,但 list、dict 等不可哈希类型不能当键;11.0True 等等价键指向同一项。

创建#

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) # 值默认为 None
from_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"] = 85
scores["math"] = 95 # 更新,顺序不变
print(scores["math"]) # 95
del scores["english"]
# print(scores["physics"]) # KeyError

get 与 setdefault#

d.get(key[, default]) — 键存在则返回值,否则返回 default(省略时为 None),不抛 KeyError

config = {"host": "localhost"}
port = config.get("port", 8080)
print(port) # 8080
print(config.get("host")) # localhost

d.setdefault(key[, default]) — 键存在则返回值;不存在则插入 key: default 并返回 defaultdefault 省略时为 None):

cache = {}
cache.setdefault("count", 0)
cache["count"] += 1
print(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)

视图支持 inlen、迭代。两个 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) # True
print(len(s)) # 3

集合运算:运算符与方法#

set ↔ set,运算符与对应方法等价;方法形式常可接受任意 iterable,运算符要求两侧为 set(官方 Note)。

运算符方法含义
s | ts.union(t, ...)并集
s & ts.intersection(t, ...)交集
s - ts.difference(t, ...)差集(在 s 不在 t)
s ^ ts.symmetric_difference(t)对称差(恰在一侧)
s <= ts.issubset(t)子集
s >= ts.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 |= ts.update(t, ...)
s &= ts.intersection_update(t, ...)
s -= ts.difference_update(t, ...)
s ^= ts.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) # 不存在 → KeyError
s.discard(99) # 不存在不报错
x = s.pop() # 任意移除一项;空 set → KeyError
s.clear()

setfrozenset 混合运算时,结果类型与左操作数一致(官方说明)。

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 相同的只读运算(unionintersection 等及对应运算符)。

容易踩的坑#

  1. {} 是 dict,set() 才是空 set。
  2. dict 键必须可哈希 —— 数字、字符串、tuple(元素皆哈希)可以;list、dict 不行。
  3. set 去重不保序 —— 要保留首次出现顺序:list(dict.fromkeys(seq))(3.7+ dict 保序),比 list(set(seq)) 稳。
  4. 集合元素必须可哈希 —— 同 dict 键;要存 list 可先 tuple(...)

附录:dict 方法全集#

摘自 Mapping Types — 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 dlen(d)iter(d)

附录:set / frozenset 方法全集#

方法setfrozenset
union / |
intersection / &
difference / -
symmetric_difference / ^
copy()
isdisjoint
issubset / <= / <
issuperset / >= / >
update / |= 等原地运算
add / remove / discard / pop / clear

另有:x in slen(s)for x in s


参考#

官方文档(中文版 可对照阅读):

  1. Mapping Types — dict — 键值操作、get / setdefault、视图
  2. Dictionary view objects
  3. Set Types — set, frozenset — 运算符与方法
  4. Dictionaries — 教程示例
  5. Sets — 教程中的集合用法

目录来源(骨架,不以它为准改语法):

  1. 菜鸟教程 · 数据结构 — dict / set 章节(去重、空 set 等 tips)
Python 札记 (5)
https://blog.chuwu.top/posts/python/python5/
作者
ChuwuYo
发布于
2026-08-28
许可协议
CC BY-NC-SA 4.0