Python 字典 (dict)
dict 是可变映射:键须可哈希,3.7+ 保留插入序;掌握读写、get、视图与常见聚合模式。
#concept
#growing
#dev
#python
#python
[!info] related notes
Python 字典 (dict)
这个概念为什么出现
索引、配置、JSON 对象、聚合计数——都是“键到值”。dict 是 Python 最重要的内置映射:平均 O(1) 查找,且自 3.7 起语言保证保留插入顺序。
[!abstract] 一句话理解
dict把可哈希键映射到任意值;用[]/get访问,视图支持遍历 keys/values/items,插入序在现代 Python 中稳定可依赖。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:活动后台按渠道聚合报名并安全读配置
# channel_dict_demo.py
# 业务意图:聚合渠道计数,安全读取可选配置键。
# 教学点:
# - 创建/写入/in;
# - get 默认值 vs KeyError;
# - setdefault 与插入序。
def aggregate_channels(rows: list[dict]) -> dict[str, int]:
counts: dict[str, int] = {}
for row in rows:
ch = row["channel"]
counts[ch] = counts.get(ch, 0) + 1
return counts
def main() -> None:
rows = [
{"user": "a", "channel": "wechat"},
{"user": "b", "channel": "app"},
{"user": "c", "channel": "wechat"},
]
counts = aggregate_channels(rows)
print("counts:", counts)
print("keys order:", list(counts)) # 插入序
config = {"timeout_s": 3}
print("retries:", config.get("retries", 1)) # 缺失不炸
# print(config["retries"]) # KeyError
# setdefault:仅当键不存在时写入
config.setdefault("retries", 2)
config.setdefault("retries", 9) # 已存在不改
print("config:", config)
if __name__ == "__main__":
main()
建议运行:
python channel_dict_demo.py
期望输出:
counts: {'wechat': 2, 'app': 1}
keys order: ['wechat', 'app']
retries: 1
config: {'timeout_s': 3, 'retries': 2}
结合场景再看三个关注点
- 聚合用
get累加是清晰模式;大量计数也可用Counter。 - 缺失键:
[]抛错,get返回默认——API 边界要选对。 - 插入序让“先出现的渠道”遍历结果可预期。
核心概念与准确模型
键约束
- 键须可哈希,哈希值应保持稳定;相等的键必须有相同哈希,哈希相同不代表相等。
- 常见键是 str、int、frozenset,以及所有元素都可哈希的 tuple;True、1、1.0 互相相等,会落在同一个键条目。
list/dict/set不能直接作键
视图
d.keys()/values()/items()是动态视图- 遍历时增删键可能抛 RuntimeError 或漏项;更新已有键的值不改变插入顺序。list(d.items()) 复制当时的键值对引用,不深拷贝值,也不是并发同步机制。
合并
- {**a, **b} 自 Python 3.5 起可用;dict 的 | 与 |= 自 3.9 起可用,重复键取右侧值。覆盖已有键保留原位置,删除后重插则移到末尾。
边界情况与反直觉行为
popvsdel:pop可带默认。- get/setdefault 的默认参数表达式都先求值;它们仅在键缺失时使用默认值,已有值为 None/0 不会触发默认。setdefault 还会插入缺失键。
- dict.fromkeys(keys, []) 会让各键共享同一个 list;需要独立列表时用字典推导式。子类/自定义映射还可能改变访问语义。
常见误区
[!warning] 常见误区:用点语法访问 dict 错误理解:
user.name与 JS 对象一样。
正确模型:dict 用user["name"];点语法是属性,属于对象字段。
工程实践
- JSON 对象常解码为 dict,但 JSON 键只能是字符串;含数字键等 Python dict 转 JSON 再读回不保证原样恢复。
- 配置层避免“字符串键魔法”散落,可集中常量。
- 需要默认工厂用
collections.defaultdict。
本节总结
dict 是映射与聚合的核心。先守住键可哈希与缺失键策略,再使用视图与合并语法。
自测题
- 为什么 list 不能当键?
get与setdefault差别?
参考答案
- list 可变不可哈希。
get只读默认;setdefault在缺失时写入并返回。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Mapping Types — dict | 文档 | dict 语义 |