Python 字典 dict 从入门到实战:一篇文章掌握常用操作

在 Python 中,dict(字典)是非常高频的数据类型。无论是保存用户信息、配置参数、接口返回数据,还是统计词频、管理通讯录,都经常会用到字典。

这篇文章会按“由简单到高级”的顺序讲解字典:先理解概念,再掌握增删改查和遍历,最后通过实战案例把知识串起来。每个知识点都配有可直接运行的 demo,建议你边看边复制测试。

一、基础入门

1. 字典是什么

字典可以理解为“键值对的集合”。

通俗一点说:字典就像一本通讯录,姓名是“键”,电话是“值”。我们想找某个人的电话时,不需要从头翻到尾,只要根据姓名这个键,就能快速拿到对应的电话号码。

字典的几个核心特点:

  • 键: 值 组成,一个键对应一个值。
  • 可以修改,比如新增联系人、修改电话号码、删除联系人。
  • 主要通过“键”查找值,而不是通过索引查找。
  • Python 3.7+ 会保留插入顺序,但字典的核心仍然是“键值映射”,不能像列表一样用位置索引访问。

先看一个生活化例子:

# 通讯录:姓名是键,电话号码是值
contacts = {
    "张三": "13800000001",
    "李四": "13800000002",
    "王五": "13800000003"
}

# 通过姓名这个键,快速找到电话
print(contacts["李四"])  # 输出:13800000002

和列表、元组简单对比:

# 列表:通过索引访问,适合保存一组有顺序的数据
names = ["张三", "李四", "王五"]
print(names[1])  # 输出:李四

# 元组:和列表类似,但创建后通常不修改
point = (10, 20)
print(point[0])  # 输出:10

# 字典:通过键访问,适合保存“名称 -> 信息”这种映射关系
student = {
    "name": "小明",
    "age": 18,
    "score": 95
}
print(student["score"])  # 输出:95

如果你关心“某个名字对应什么值”,字典通常比列表更合适。

2. 字典的基础语法

方式一:直接使用 {} 创建字典

这是最常见的创建方式。

# 使用大括号创建字典
student = {
    "name": "小明",    # 键是字符串,值也是字符串
    "age": 18,         # 键是字符串,值是数字
    "hobbies": ["篮球", "阅读"]  # 值可以是列表
}

print(student)
print(student["name"])     # 输出:小明
print(student["hobbies"])  # 输出:['篮球', '阅读']

字典的键和值有不同要求:

  • 键必须是不可变类型,比如字符串、数字、元组。
  • 值可以是任意类型,比如字符串、数字、列表、字典等。
# 合法的键:字符串、数字、元组
example = {
    "name": "Python",
    1: "数字也可以作为键",
    ("x", "y"): "元组也可以作为键"
}

print(example["name"])
print(example[1])
print(example[("x", "y")])
方式二:使用 dict() 函数创建字典

dict() 可以通过关键字参数创建字典。

# 使用 dict() 创建字典
student = dict(name="小红", age=17, score=88)

print(student)          # 输出:{'name': '小红', 'age': 17, 'score': 88}
print(student["age"])   # 输出:17

注意:使用 dict(name="小红") 这种写法时,键会自动变成字符串 "name",不能写成中文变量名或带空格的名字。

dict() 也可以接收键值对列表:

# 每个小元组表示一个键值对
pairs = [("name", "小刚"), ("age", 19), ("score", 92)]

student = dict(pairs)

print(student)  # 输出:{'name': '小刚', 'age': 19, 'score': 92}
方式三:创建空字典

空字典适合先创建容器,后续再逐步添加数据。

# 创建空字典
contacts = {}

# 后续新增键值对
contacts["张三"] = "13800000001"
contacts["李四"] = "13800000002"

print(contacts)

也可以使用 dict() 创建空字典:

# 另一种空字典写法
settings = dict()

settings["theme"] = "dark"
settings["font_size"] = 16

print(settings)

3. 字典的基础访问

字典通过“键”访问对应的值。

正常访问
student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

# 使用 键 获取对应的 值
print(student["name"])   # 输出:小明
print(student["score"])  # 输出:95
访问不存在的键会报错

如果键不存在,直接访问会触发 KeyError

student = {
    "name": "小明",
    "age": 18
}

# 演示报错场景:使用 try 捕获异常,避免程序直接中断
try:
    print(student["score"])  # score 这个键不存在
except KeyError:
    print("访问失败:字典中没有 score 这个键")

避免报错的一个简单技巧:访问前先判断键是否存在。

student = {
    "name": "小明",
    "age": 18
}

if "score" in student:
    print(student["score"])
else:
    print("score 不存在,先设置默认分数")

二、基础操作

1. 字典的增删改操作

新增键值对

如果给一个不存在的键赋值,就是新增键值对。

student = {
    "name": "小明",
    "age": 18
}

# 新增一个键值对:score -> 95
student["score"] = 95

print(student)
修改已有键的值

如果键已经存在,再次赋值就是修改。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

# 修改已有键 score 的值
student["score"] = 100

print(student)  # score 从 95 变成 100
使用 del 删除键值对

del 会直接删除指定键值对,不会返回被删除的值。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

# 删除 age 这个键值对
del student["age"]

print(student)

如果删除不存在的键,也会触发 KeyError

student = {"name": "小明"}

try:
    del student["score"]  # score 不存在
except KeyError:
    print("删除失败:score 不存在")
使用 pop() 删除键值对

pop() 删除键值对时,会返回被删除的值。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

# pop 会删除 score,并把被删除的值返回
removed_score = student.pop("score")

print("被删除的分数:", removed_score)
print("删除后的字典:", student)

pop()del 的区别:

  • del dict[key]:只删除,不返回被删除的值。
  • dict.pop(key):删除,并返回被删除的值。
  • pop() 可以设置默认值,键不存在时不报错。
student = {"name": "小明"}

# 如果 score 不存在,返回默认值 0,不会报错
score = student.pop("score", 0)

print("删除结果:", score)
print(student)

2. 字典的遍历

遍历就是把字典中的内容一个个取出来处理。

遍历所有键

默认遍历字典时,拿到的是键。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

# 默认遍历字典,得到的是每一个键
for key in student:
    print("键:", key)

也可以显式使用 keys()

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

for key in student.keys():
    print("键:", key)

适用场景:只关心字典有哪些字段,比如检查用户信息里有哪些属性。

遍历所有值

使用 values() 可以拿到所有值。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

for value in student.values():
    print("值:", value)

适用场景:只关心数据本身,比如统计所有成绩。

scores = {
    "小明": 95,
    "小红": 88,
    "小刚": 92
}

total = 0
for score in scores.values():
    total += score

print("总分:", total)
遍历所有键值对

使用 items() 可以同时拿到键和值。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

for key, value in student.items():
    print(key, "=>", value)

items() 的优势是:不需要先拿键再通过 student[key] 取值,代码更清晰。

scores = {
    "小明": 95,
    "小红": 88,
    "小刚": 92
}

for name, score in scores.items():
    print(f"{name} 的成绩是 {score}")

3. 字典的基础判断

判断某个键是否存在,使用 innot in

判断成功的场景
contacts = {
    "张三": "13800000001",
    "李四": "13800000002"
}

name = "张三"

if name in contacts:
    print(f"{name} 在通讯录中,电话是 {contacts[name]}")
else:
    print(f"{name} 不在通讯录中")
判断失败的场景
contacts = {
    "张三": "13800000001",
    "李四": "13800000002"
}

name = "王五"

if name not in contacts:
    print(f"{name} 不在通讯录中,可以新增联系人")
else:
    print(f"{name} 已存在")

注意:in 判断的是键,不是值。

contacts = {
    "张三": "13800000001"
}

print("张三" in contacts)          # True,张三是键
print("13800000001" in contacts)  # False,电话号码是值,不是键

三、进阶操作

1. 字典的常用方法

get():安全获取值

get() 用来根据键获取值。和 dict[key] 不同的是:键不存在时,get() 不会报错。

student = {
    "name": "小明",
    "age": 18
}

# 直接访问不存在的键会报错,所以这里使用 get()
score = student.get("score")

print(score)  # 输出:None

get() 可以设置默认值。

student = {
    "name": "小明",
    "age": 18
}

# 如果 score 不存在,就返回默认值 0
score = student.get("score", 0)

print("成绩:", score)

对比直接访问:

student = {"name": "小明"}

try:
    print(student["score"])  # 不存在会报错
except KeyError:
    print("直接访问不存在的键会报错")

print(student.get("score", "暂无成绩"))  # 不报错,返回默认值
keys():获取所有键
student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

keys = student.keys()

print(keys)          # dict_keys(['name', 'age', 'score'])
print(list(keys))    # 转成列表后更方便查看
values():获取所有值
student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

values = student.values()

print(values)
print(list(values))  # 输出:['小明', 18, 95]
items():获取所有键值对
student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

items = student.items()

print(items)
print(list(items))  # 输出:[('name', '小明'), ('age', 18), ('score', 95)]

items() 常用于循环中:

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

for key, value in student.items():
    print(f"{key}: {value}")
update():合并或批量修改字典

update() 可以把另一个字典的数据合并进来。

student = {
    "name": "小明",
    "age": 18
}

new_info = {
    "score": 95,
    "city": "北京"
}

# 把 new_info 合并到 student 中
student.update(new_info)

print(student)

如果两个字典中有相同的键,后面的值会覆盖前面的值。

student = {
    "name": "小明",
    "age": 18,
    "score": 80
}

new_info = {
    "score": 95,   # 会覆盖原来的 score
    "city": "北京"
}

student.update(new_info)

print(student)
clear():清空字典

clear() 会删除字典中的所有键值对,但字典对象本身还在。

student = {
    "name": "小明",
    "age": 18,
    "score": 95
}

student.clear()

print(student)  # 输出:{}

2. 字典的嵌套

实际开发中,字典里经常会嵌套列表或字典。

字典中包含列表

比如保存一个学生的多个爱好:

student = {
    "name": "小明",
    "age": 18,
    "hobbies": ["篮球", "阅读", "编程"]
}

# 访问整个爱好列表
print(student["hobbies"])

# 访问第一个爱好
print(student["hobbies"][0])

# 新增一个爱好
student["hobbies"].append("跑步")

print(student)

访问逻辑可以拆开看:

student = {
    "name": "小明",
    "hobbies": ["篮球", "阅读"]
}

hobbies = student["hobbies"]  # 第一步:通过键拿到列表
first_hobby = hobbies[0]      # 第二步:通过索引拿到列表元素

print(first_hobby)
字典中包含字典

比如保存多个学生的信息:学生姓名是键,学生详细信息是值。

students = {
    "小明": {
        "age": 18,
        "score": 95
    },
    "小红": {
        "age": 17,
        "score": 88
    }
}

# 访问小明的完整信息
print(students["小明"])

# 访问小明的年龄
print(students["小明"]["age"])

# 修改小红的成绩
students["小红"]["score"] = 90

print(students)

嵌套层级的访问逻辑是“一层一层往里取”:

students = {
    "小明": {"age": 18, "score": 95}
}

ming_info = students["小明"]     # 第一层:通过姓名取到内部字典
ming_score = ming_info["score"]  # 第二层:从内部字典取成绩

print(ming_score)

也可以新增一个学生:

students = {
    "小明": {"age": 18, "score": 95}
}

# 新增一个键值对,值是一个新的字典
students["小刚"] = {
    "age": 19,
    "score": 92
}

print(students)

3. 字典推导式

字典推导式可以用更简洁的方式创建字典。

基本语法:

# {键表达式: 值表达式 for 变量 in 可迭代对象}
示例一:把两个列表转换成字典
names = ["小明", "小红", "小刚"]
scores = [95, 88, 92]

# zip(names, scores) 会把两个列表按位置配对
score_dict = {name: score for name, score in zip(names, scores)}

print(score_dict)

不用推导式时,通常要这样写:

names = ["小明", "小红", "小刚"]
scores = [95, 88, 92]

score_dict = {}
for name, score in zip(names, scores):
    score_dict[name] = score

print(score_dict)

字典推导式的优势是:代码更短,也更容易看出“生成字典”的目的。

示例二:对字典的值进行处理

给每个学生的成绩加 5 分:

scores = {
    "小明": 90,
    "小红": 82,
    "小刚": 87
}

# 遍历原字典的键值对,生成一个新字典
new_scores = {name: score + 5 for name, score in scores.items()}

print(new_scores)
示例三:筛选符合条件的数据

只保留成绩大于等于 90 的学生:

scores = {
    "小明": 95,
    "小红": 88,
    "小刚": 92,
    "小李": 76
}

# if score >= 90 表示只保留满足条件的键值对
excellent_scores = {
    name: score
    for name, score in scores.items()
    if score >= 90
}

print(excellent_scores)

四、实战案例

案例一:通讯录管理

需求:

  • 新增联系人
  • 查询联系人
  • 修改联系人电话
  • 删除联系人

实现思路:

  • 使用字典保存通讯录,姓名作为键,电话作为值。
  • 新增和修改都可以使用 contacts[name] = phone
  • 查询前使用 in 判断联系人是否存在。
  • 删除时使用 pop(),方便拿到被删除的电话。

完整代码如下:

# 通讯录管理案例

contacts = {}


def add_contact(name, phone):
    """新增联系人"""
    if name in contacts:
        print(f"{name} 已存在,如需修改请调用 update_contact")
        return

    contacts[name] = phone
    print(f"新增成功:{name} -> {phone}")


def query_contact(name):
    """查询联系人"""
    phone = contacts.get(name)

    if phone is None:
        print(f"未找到联系人:{name}")
    else:
        print(f"{name} 的电话是:{phone}")


def update_contact(name, new_phone):
    """修改联系人电话"""
    if name not in contacts:
        print(f"修改失败:{name} 不存在")
        return

    old_phone = contacts[name]
    contacts[name] = new_phone
    print(f"修改成功:{name}{old_phone} -> {new_phone}")


def delete_contact(name):
    """删除联系人"""
    removed_phone = contacts.pop(name, None)

    if removed_phone is None:
        print(f"删除失败:{name} 不存在")
    else:
        print(f"删除成功:{name},原电话是 {removed_phone}")


def show_all_contacts():
    """展示全部联系人"""
    if not contacts:
        print("通讯录为空")
        return

    print("当前通讯录:")
    for name, phone in contacts.items():
        print(f"- {name}: {phone}")


# 模拟使用流程
add_contact("张三", "13800000001")
add_contact("李四", "13800000002")
query_contact("张三")
update_contact("李四", "13900000002")
delete_contact("张三")
show_all_contacts()

这个案例串联了字典的新增、查询、修改、删除、get()pop()items() 等常用操作。

案例二:学生成绩统计

需求:

  • 保存多个学生的多门成绩。
  • 查询某个学生的成绩。
  • 修改某个学生某门课成绩。
  • 统计每个学生总分和平均分。

实现思路:

  • 外层字典:学生姓名 -> 成绩字典。
  • 内层字典:科目 -> 分数。
  • 通过 students[name][subject] 访问具体成绩。
  • 使用 values() 统计分数。

完整代码如下:

# 学生成绩统计案例

students = {
    "小明": {
        "语文": 90,
        "数学": 95,
        "英语": 88
    },
    "小红": {
        "语文": 86,
        "数学": 91,
        "英语": 93
    },
    "小刚": {
        "语文": 78,
        "数学": 84,
        "英语": 80
    }
}


def query_student(name):
    """查询某个学生的所有成绩"""
    if name not in students:
        print(f"未找到学生:{name}")
        return

    print(f"{name} 的成绩:")
    for subject, score in students[name].items():
        print(f"- {subject}: {score}")


def update_score(name, subject, score):
    """修改某个学生某门课成绩"""
    if name not in students:
        print(f"修改失败:学生 {name} 不存在")
        return

    if subject not in students[name]:
        print(f"修改失败:{name} 没有 {subject} 这门课")
        return

    old_score = students[name][subject]
    students[name][subject] = score
    print(f"修改成功:{name}{subject}{old_score} -> {score}")


def print_statistics():
    """统计每个学生的总分和平均分"""
    print("成绩统计:")

    for name, score_dict in students.items():
        total = sum(score_dict.values())
        average = total / len(score_dict)
        print(f"{name}: 总分 {total},平均分 {average:.2f}")


# 模拟使用流程
query_student("小明")
update_score("小刚", "数学", 90)
print_statistics()

这个案例重点练习了嵌套字典、items()values()、键存在判断和修改操作。

五、注意事项:常见坑与正确写法

1. 字典的键必须是不可变类型

列表是可变类型,不能作为字典的键。

错误示例:

try:
    data = {
        ["Python", "Java"]: "编程语言"  # 列表不能作为键
    }
except TypeError as e:
    print("创建失败:", e)

正确示例:

# 元组是不可变类型,可以作为键
data = {
    ("Python", "Java"): "编程语言"
}

print(data[("Python", "Java")])

2. 字典不能通过索引访问

Python 3.7+ 的字典会保留插入顺序,但它仍然不是列表,不能使用 dict[0] 这种方式访问“第一个元素”。

错误示例:

student = {
    "name": "小明",
    "age": 18
}

try:
    print(student[0])  # 这里的 0 会被当作键,而不是索引
except KeyError:
    print("访问失败:字典没有 0 这个键")

正确示例:

student = {
    "name": "小明",
    "age": 18
}

# 想遍历字典内容,应该使用 items()
for key, value in student.items():
    print(key, value)

3. 删除键前建议先判断是否存在

直接删除不存在的键会报错。

错误示例:

student = {"name": "小明"}

try:
    del student["score"]
except KeyError:
    print("删除失败:score 不存在")

正确示例一:先判断再删除。

student = {"name": "小明"}

if "score" in student:
    del student["score"]
else:
    print("score 不存在,不需要删除")

正确示例二:使用 pop() 设置默认值。

student = {"name": "小明"}

removed_score = student.pop("score", None)

if removed_score is None:
    print("score 不存在")
else:
    print("删除的成绩是:", removed_score)

4. get() 的默认值要按业务设置

get() 的默认值不是固定的,应该根据业务含义设置。

student = {
    "name": "小明"
}

# 如果成绩不存在,用 0 表示暂无成绩
score = student.get("score", 0)
print("成绩:", score)

# 如果城市不存在,用“未知”更适合展示给用户
city = student.get("city", "未知")
print("城市:", city)

5. 遍历字典时不要直接修改字典大小

一边遍历字典,一边新增或删除键,容易触发错误。

错误示例:

scores = {
    "小明": 95,
    "小红": 58,
    "小刚": 92
}

try:
    for name, score in scores.items():
        if score < 60:
            del scores[name]  # 遍历时删除键,容易报错
except RuntimeError as e:
    print("操作失败:", e)

正确示例:先把要删除的键收集起来,再统一删除。

scores = {
    "小明": 95,
    "小红": 58,
    "小刚": 92
}

to_delete = []

for name, score in scores.items():
    if score < 60:
        to_delete.append(name)

for name in to_delete:
    del scores[name]

print(scores)

也可以遍历键的副本:

scores = {
    "小明": 95,
    "小红": 58,
    "小刚": 92
}

# list(scores.keys()) 会生成一个键列表副本
for name in list(scores.keys()):
    if scores[name] < 60:
        del scores[name]

print(scores)

总结

字典是 Python 中非常重要的数据类型,核心思想就是“通过键快速找到值”。你需要重点掌握这些内容:

  • 创建字典:{}dict()、空字典。
  • 访问数据:dict[key]get()
  • 增删改查:赋值新增或修改,delpop() 删除。
  • 遍历数据:keys()values()items()
  • 判断键是否存在:innot in
  • 处理复杂结构:嵌套字典和字典推导式。

学习字典最好的方式就是多写小练习。你可以从通讯录、学生成绩、商品库存、接口返回数据解析这些场景开始练起。只要理解了“键值对”这个核心概念,字典在日常开发中会变得非常顺手。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐