Z
ZHANK
数据结构

字典 (Dict)

掌握字典键值对操作、遍历方法、嵌套与推导式

字典 (Dict)

字典是 Python 中最重要的数据结构之一。它用键值对存储数据,查找速度极快。

学完本章你将掌握: 字典创建、增删改查、安全访问、遍历方式、嵌套与推导式。


一、字典是什么

想象一个真实的字典——你通过"单词"(键)来查找"释义"(值)。Python 字典同理:

python
# 键 → 值
person = {
    "name": "小明",
    "age": 20,
    "city": "北京",
    "skills": ["Python", "JavaScript"]
}

print(person["name"])     # 小明
print(person["skills"])   # ['Python', 'JavaScript']

为什么用字典而不是列表? 因为查找快。字典通过哈希表实现,查找一个键是 O(1) 的时间——不管字典有多大。


二、创建字典

python
# 方式1:花括号
d1 = {"a": 1, "b": 2}

# 方式2:dict() 函数
d2 = dict(name="小明", age=20)  # 键不用加引号
d3 = dict([("a", 1), ("b", 2)]) # 从元组列表创建

# 方式3:字典推导式
d4 = {x: x**2 for x in range(5)}

# 空字典
empty = {}

💡 键的要求:字典的键必须是不可变类型——字符串、数字、元组都可以。列表不行(因为可变)。

python
# ✅ 合法的键
{1: "a", "name": "b", (1,2): "c"}

# ❌ 不合法的键(会报错)
# {[1,2]: "a"}  # TypeError: unhashable type: 'list'

三、访问与修改

python
person = {"name": "小明", "age": 20}

# 直接访问(键不存在报 KeyError)
print(person["name"])     # 小明

# 安全访问:get()(推荐)
print(person.get("name"))       # 小明
print(person.get("phone"))      # None(键不存在,不报错)
print(person.get("phone", "无"))  # 无(自定义默认值)

# 添加/修改
person["email"] = "xm@test.com"  # 键不存在 → 添加
person["age"] = 21               # 键已存在 → 修改

💡 为什么推荐 get()person["phone"] 如果 phone 不存在会直接崩溃。person.get("phone", "无") 会优雅地返回默认值。在生产代码中始终用 get()


四、删除元素

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

# pop():删除并返回
val = d.pop("b")
print(val)   # 2
print(d)     # {'a': 1, 'c': 3}

# popitem():删除最后一项(Python 3.7+ 保证插入顺序)
d["d"] = 4
last = d.popitem()
print(last)  # ('d', 4)

# del:直接删除
del d["a"]
print(d)     # {'c': 3}

# clear():清空
d.clear()
print(d)     # {}

五、遍历字典

python
scores = {"语文": 90, "数学": 85, "英语": 92}

# 遍历键
for subject in scores:
    print(subject, end=" ")  # 语文 数学 英语

# 遍历值
for score in scores.values():
    print(score, end=" ")    # 90 85 92

# 遍历键值对(最常用!)
for subject, score in scores.items():
    print(f"{subject}: {score}分")

六、检查键是否存在

python
person = {"name": "小明", "age": 20}

# in 操作符(推荐)
if "name" in person:
    print(person["name"])

if "phone" not in person:
    person["phone"] = "未知"

# 用 get 一行搞定
phone = person.get("phone", "无")

💡 性能in 对字典是 O(1),非常快。不像列表的 in 是 O(n)。这就是为什么经常用字典来做"快速查找"。


七、字典方法大全

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

# keys() — 所有键
print(d.keys())         # dict_keys(['a', 'b', 'c'])

# values() — 所有值
print(d.values())       # dict_values([1, 2, 3])

# items() — 所有键值对
print(d.items())        # dict_items([('a',1), ('b',2), ('c',3)])

# len() — 键值对数量
print(len(d))           # 3

# update() — 合并另一个字典
d.update({"b": 20, "d": 4})  # 键冲突时覆盖
print(d)  # {'a': 1, 'b': 20, 'c': 3, 'd': 4}

# | 合并(Python 3.9+)
a = {"x": 1, "y": 2}
b = {"y": 99, "z": 3}
print(a | b)  # {'x': 1, 'y': 99, 'z': 3}

八、嵌套字典

python
# 真实场景:学生管理系统
students = {
    "001": {
        "name": "小明",
        "age": 15,
        "scores": {"语文": 90, "数学": 85}
    },
    "002": {
        "name": "小红",
        "age": 16,
        "scores": {"语文": 88, "数学": 92}
    }
}

# 访问嵌套数据
print(students["001"]["name"])           # 小明
print(students["002"]["scores"]["数学"])  # 92

# 安全访问嵌套字典
name = students.get("003", {}).get("name", "未知")
print(name)  # 未知

九、字典推导式

python
# 基本形式
squares = {x: x**2 for x in range(1, 6)}
print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 带条件
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# 交换键和值
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped)  # {1: 'a', 2: 'b', 3: 'c'}

# 实战:筛选分数 > 85 的学生
scores = {"小明": 85, "小红": 92, "小刚": 78, "小丽": 95}
top = {k: v for k, v in scores.items() if v > 85}
print(top)  # {'小红': 92, '小丽': 95}

十、defaultdict——带默认值的字典

python
from collections import defaultdict

# 普通字典:键不存在会报错
d = {}
# d["count"] += 1  # KeyError!

# defaultdict:键不存在时自动创建默认值
dd = defaultdict(int)
dd["count"] += 1
print(dd["count"])  # 1

dd = defaultdict(list)
dd["students"].append("小明")
print(dd["students"])  # ['小明']

小结

  1. {key: value} 创建字典,键必须不可变
  2. dict[key]dict.get(key, default) 两种访问方式
  3. .items() .keys() .values() 分别遍历键值对、键、值
  4. 字典推导式和 defaultdict 是高级但常用的技巧
  5. in 对字典是 O(1),非常适合做快速查找

小练习

  1. 创建一个字典存储你的个人信息(姓名、年龄、城市、技能列表)
  2. 统计 "hello world hello python world" 中每个单词出现的次数(用字典)
  3. 用字典推导式把 {"a": 1, "b": 2, "c": 3} 中的值都翻倍

💬 下一章预告:学完字典,下一章学习函数基础——把代码打包成可复用的工具。