Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Dict (字典)

下面是一份 最实用、最清晰、最开发者视角的 Python dict 全面指南,包含:基础、进阶、最佳实践、性能优化、常见坑、高级用法、字典推导、合并技巧、排序技巧、默认字典、不可变字典、应用场景等。

内容非常贴近实际项目开发(FastAPI、SQLAlchemy、业务代码都经常用)。

1. dict 基础:核心要点

d = {"name": "martin", "age": 18}

dict 的 3 个关键特性:

  1. 无序但保持插入顺序(Python 3.7+)
  2. key 必须可哈希(不可变)
  3. 查询复杂度 O(1) —— 哈希表

常用 API

d.keys()
d.values()
d.items()
d.get("key", default)
d.pop("key")
d.update(other_dict)

2. dict 的创建方式

① 字面量(最常用)

a = {"x": 1, "y": 2}

② dict() 构造函数

b = dict(x=1, y=2)

③ 从列表构建

pairs = [("x", 1), ("y", 2)]
dict(pairs)

④ 使用字典推导式

d = {i: i * 2 for i in range(5)}

3. 访问元素:推荐方式

✅ d.get(key)(不会抛异常)

d.get("name")         # 有返回值
d.get("missing")      # None
d.get("missing", 0)   # 0

❌ 不推荐

d["missing"]  # KeyError

4. 更新字典的多种方式

① 赋值(最常见)

d["x"] = 100

② update()

d.update({"y": 200})

③ 使用 解包合并(3.9+ 推荐)

new_d = d1 | d2          # 创建新字典
d1 |= d2                 # in-place 更新

④ setdefault(用于多个层级)

d.setdefault("config", {})["port"] = 3306

5. 字典推导式(Pythonic 必备)

生成新字典

{i: i*i for i in range(10) if i % 2 == 0}

转换 key/value

{k: v.upper() for k, v in d.items()}

过滤字典

{k: v for k, v in d.items() if v is not None}

6. 按 key/value 排序字典(返回列表)

按 key 排序

sorted(d.items(), key=lambda x: x[0])

按 value 排序

sorted(d.items(), key=lambda x: x[1])

排序后转换回 dict(Python 3.7+)

dict(sorted(d.items(), key=lambda x: x[1]))

7. 字典的高级用法

7.1 default dict(避免 KeyError)

适合统计分类、计数等:

from collections import defaultdict

d = defaultdict(int)
d["a"] += 1  # 不会报错

嵌套结构:

d = defaultdict(lambda: defaultdict(int))

7.2 Counter(最强计数器)

比自己写逻辑快太多:

from collections import Counter
Counter("hello world")

7.3 OrderedDict(已不常用)

因为 3.7 之后 dict 就保持插入顺序了。

7.4 MappingProxyType(只读字典)

from types import MappingProxyType

d = {"x": 1}
readonly = MappingProxyType(d)

修改 d,readonly 同步变化。

7.5 链式字典(ChainMap)

用于“多层 fallback 配置”:

from collections import ChainMap

final = ChainMap(user_config, system_config, default_config)

8. 性能:dict 为什么快?

因为哈希表 + O(1) 平均查询时间。

性能结论:

  • 查找:O(1)
  • 更新:O(1)
  • 删除:O(1)
  • 遍历:和长度成正比

比 list 查找快太多。

9. 常见坑与最佳实践

❌ 1) key 必须可哈希

不能用 list 或 dict 做 key

{[1,2]: "x"}  # TypeError

✅ 可以使用元组

{(1,2): "x"}

❌ 2) 不要修改遍历中的字典

for k in d:
    d.pop(k)   # RuntimeError

✅ 正确写法:

for k in list(d):
    d.pop(k)

❌ 3) update() 会覆盖同名 key

d.update({"a": 100})  # 覆盖

❌ 4) 使用 is 判断值

if x is 1:  # 错误

✅ 用 ==

10. 字典最佳实践(务必掌握)

使用 .get()

避免 KeyError。

大量计数 -> Counter

比手写循环更快。

合并字典用 |(Python 3.9+)

final = config_default | config_env | config_user

使用 dictionary comprehension 清理数据

clean = {k: v for k, v in raw.items() if v}

JSON 数据映射到字典,最好用 dataclass 或 pydantic

避免 key 写错。

11. 字典在实际项目中的应用(非常实用)

① FastAPI 请求体 -> 字典

用于字段过滤:

data = request.dict(exclude_none=True)

② SQLAlchemy 查询结果 -> 字典

row = session.execute(stmt).mappings().first()

③ 权限系统(Casbin / RBAC)

permissions = list of dict

{"module": "user", "action": "read", "path": "/users"}

④ JSON 响应返回

return {"code": 0, "msg": "ok", "data": result}

字典的打包解包示例

以下是 最常用、最好理解的 Python 字典 “打包 / 解包” 示例(包括 ⭐高级工程常用技巧)。非常实用!

🟦 1. 字典解包(Dictionary Unpacking)

** 用于函数参数

把字典展开成关键字参数传入函数:

def foo(a, b, c):
    print(a, b, c)

data = {"a": 1, "b": 2, "c": 3}

foo(**data)

输出:

1 2 3

🟩 2. 字典合并(用 ** 解包)

Python 3.5+:

d1 = {"a": 1, "b": 2}
d2 = {"b": 20, "c": 3}

merged = {**d1, **d2}
print(merged)

输出:

{'a': 1, 'b': 20, 'c': 3}

d2 覆盖 d1 的同名 key。

🔹 用于合并配置、合并 JSON、更新参数非常常见。

🟨 3. 将多个变量打包成字典(常用)

name = "jack"
age = 18

info = {"name": name, "age": age}
print(info)

更 Pythonic 的写法:使用字面量

info = dict(name=name, age=age)

🟧 4. 从字典中解包多个值(常用)

经典写法:

user = {"name": "jack", "age": 18}

name, age = user["name"], user["age"]

更优雅写法:

name, age = (user[k] for k in ("name", "age"))

🟥 5. for 循环中解包 items()

d = {"a": 1, "b": 2, "c": 3}

for key, value in d.items():
    print(key, value)

🟦 6. 解包某些 key(工程常用)

从字典中取出几个 key 到新的字典:

d = {"a": 1, "b": 2, "c": 3}

subset = {k: d[k] for k in ("a", "c")}
print(subset)

输出:

{'a': 1, 'c': 3}

🟩 7. 动态构造字典(自动解包变量)

比如 API 返回字段:

code = "600001"
price = 12.4
volume = 30000

data = {"code": code, "price": price, "volume": volume}

高级写法:使用 locals()

data = {k: v for k, v in locals().items() if k in ("code", "price", "volume")}

🟨 8. 使用解包来更新字典

config = {"host": "localhost", "port": 3306}

new_config = {**config, "port": 3307, "debug": True}
print(new_config)

🟧 9. 用 ** 解包默认配置 + 用户配置(最常见)

default_cfg = {"retry": 3, "timeout": 10}
user_cfg = {"timeout": 5}

cfg = {**default_cfg, **user_cfg}

最终:

{'retry': 3, 'timeout': 5}

用于:

  • 函数配置
  • 数据库连接配置
  • HTTP 请求参数
  • FastAPI 入参处理

🟥 10. 将元组列表解包成字典

pairs = [("a", 1), ("b", 2)]
d = dict(pairs)

🟩 Bonus:解包字典 keys / values(常用)

keys = [*d]  # 等同于 list(d.keys())
values = [*d.values()]
items = [*d.items()]

📌 总结

字典打包

  • 变量 -> 字典:{"k": var}
  • 多个字典 -> 新字典:{**d1, **d2}

字典解包

  • 函数传参:foo(**d)
  • 提取 key:a, b = d["a"], d["b"]
  • items 解包:for k, v in d.items()