1. 映射
字典(dictionary)用于保存一组「键:值」关系。知道一个键,就可以找到它对应的值,因此字典特别适合表示用户信息、配置项、接口请求和模型参数。
使用花括号创建字典,键和值之间使用冒号,多个键值对之间使用逗号:
1user = {2"name": "小明",3"age": 18,4"is_member": True,5}67print(user)
字典的键必须是唯一且可哈希的类型,常见的是字符串、整数和元组;列表和另一个字典不能作为键。值可以是任意类型:
1data = {2"name": "小明",31: "第一个版本",4(2026, 8): "发布日期",5}67print(data)
如果重复写入同一个键,后面的值会覆盖前面的值:
1scores = {2"小明": 82,3"小明": 95,4}56print(scores) # {'小明': 95}
Python 3.7 及以上版本会保留字典键的插入顺序,但字典的核心仍然是键值查找,不应该把它当成列表使用位置索引。
也可以使用 dict() 创建字典:
1user = dict(name="小明", age=18)23print(user) # {'name': '小明', 'age': 18}
2. 读取
使用方括号和键可以读取字典中的值:
1user = {2"name": "小明",3"age": 18,4}56print(user["name"]) # 小明7print(user["age"]) # 18
如果键不存在,方括号读取会抛出 KeyError:
1user = {"name": "小明"}23# print(user["email"]) # KeyError
不确定键是否存在时,可以先使用 in,或者使用 get():
01user = {"name": "小明"}0203if "email" in user:04print(user["email"])0506email = user.get("email")07city = user.get("city", "未知城市")0809print(email) # None10print(city) # 未知城市
get(key, default) 在键存在时返回原值,在键不存在时返回默认值,而且不会修改字典。处理请求参数或外部数据时,get() 通常比直接使用方括号更安全。
需要区分「键不存在」和「键存在但值为 None」时,不能只判断 get() 的结果:
1data = {"result": None}23if "result" in data:4print("result 这个键存在")56print(data.get("result")) # None
3. 修改
给一个不存在的键赋值,就会新增键值对;给已有键赋值,就会更新它的值:
1user = {"name": "小明"}23user["age"] = 184user["name"] = "小明同学"56print(user)
update() 可以一次添加或更新多个键值对:
1user = {2"name": "小明",3"age": 18,4}56user.update({"age": 19, "city": "上海"})78print(user)
setdefault() 在键不存在时写入默认值,在键已经存在时保留原值:
1user = {"name": "小明"}23user.setdefault("tags", [])4user["tags"].append("Python")56print(user) # {'name': '小明', 'tags': ['Python']}
两个字典可以使用 | 合并,右侧字典的值会覆盖左侧同名键。|= 会把合并结果写回左侧字典:
1default_config = {"timeout": 30, "retries": 2}2custom_config = {"timeout": 60}34config = default_config | custom_config5default_config |= {"debug": True}67print(config) # {'timeout': 60, 'retries': 2}8print(default_config) # {'timeout': 30, 'retries': 2, 'debug': True}
删除字典中的数据有几种方式:
01user = {02"name": "小明",03"age": 18,04"city": "上海",05}0607del user["age"]08city = user.pop("city", "未知城市")09last_item = user.popitem()1011print(city) # 上海12print(last_item) # ('name', '小明')13print(user) # {}
del 删除指定键,但键不存在时会抛出 KeyError;pop() 删除指定键并返回值,还可以提供默认值;popitem() 删除并返回最后插入的键值对。需要清空所有数据时使用 clear():
1data = {"name": "小明", "age": 18}2data.clear()34print(data) # {}
4. 遍历
直接遍历字典时,循环变量得到的是键:
1user = {2"name": "小明",3"age": 18,4}56for key in user:7print(key)
使用 keys() 可以明确表达「遍历所有键」,使用 values() 可以只遍历值:
1scores = {"小明": 82, "小红": 95, "小李": 58}23for name in scores.keys():4print(name)56for score in scores.values():7print(score)
最常用的方式是使用 items() 同时得到键和值:
1scores = {"小明": 82, "小红": 95, "小李": 58}23for name, score in scores.items():4if score >= 60:5print(f"{name}:通过")
in 默认检查的是键,不是值:
1scores = {"小明": 82, "小红": 95}23print("小明" in scores) # True4print(82 in scores) # False5print(82 in scores.values()) # True
遍历字典时不要一边遍历字典本身,一边直接新增或删除键,否则可能抛出 RuntimeError。如果确实需要修改键,可以先遍历 list(data) 得到一个独立的键列表:
1data = {"a": 1, "b": 2, "c": 3}23for key in list(data):4if data[key] < 2:5del data[key]67print(data) # {'b': 2, 'c': 3}
5. 嵌套
字典的值可以是另一个字典或列表,因此可以表达层次化数据:
01user = {02"profile": {03"name": "小明",04"city": "上海",05},06"tags": ["Python", "AI"],07}0809print(user["profile"]["name"]) # 小明10print(user["tags"][0]) # Python
访问多层结构时,任意一层缺少键都可能抛出 KeyError。数据来自接口或用户输入时,可以逐层使用 get(),或者先进行结构校验:
1data = {"profile": {"name": "小明"}}23profile = data.get("profile", {})4city = profile.get("city", "未知城市")56print(city) # 未知城市
列表中保存多个字典是接口数据中很常见的结构:
01users = [02{"name": "小明", "active": True},03{"name": "小红", "active": False},04{"name": "小李", "active": True},05]0607active_names = [08user["name"]09for user in users10if user["active"]11]1213print(active_names) # ['小明', '小李']
6. 实例
FastAPI 请求体和 LangChain 消息通常都可以先用字典表达。下面模拟一个聊天请求:
01request = {02"model": "deepseek-chat",03"messages": [04{"role": "user", "content": "请介绍一下 Python。"},05],06"temperature": 0.2,07}0809request["messages"].append({10"role": "system",11"content": "请使用中文回答。",12})1314for message in request["messages"]:15print(f"{message['role']}:{message['content']}")
这个结构中,外层字典保存模型配置和消息列表,消息列表中的每一项又是一个字典。实际项目里,Pydantic 模型会负责校验这类请求,但理解字典结构仍然是读懂请求数据的基础。
字典也常用于统计分类结果:
1tags = ["python", "ai", "python", "web", "ai"]2counts = {}34for tag in tags:5counts[tag] = counts.get(tag, 0) + 167print(counts) # {'python': 2, 'ai': 2, 'web': 1}
counts.get(tag, 0) 在第一次遇到标签时返回 0,之后每次遇到同一个标签就把计数加 1。这是字典在实际数据处理中非常常见的模式。
字典可以转换为 JSON 字符串,方便在接口或文件中传输:
1import json23data = {4"name": "小明",5"topics": ["Python", "LangChain"],6}78text = json.dumps(data, ensure_ascii=False)9print(text)