12.Python中字典完全指南

1. 什么是字典(dict)?

在 Python 中,字典(dict) 是一种用来存放“键—值对(key–value)”的数据结构。

  • 列表:是“按顺序排好的一排格子”(每个格子有索引 0、1、2…)
  • 字典:更像是“一个小型的电话簿 / 配置表”,通过键(key)来查对应的值(value)

简单理解:

  • 键(key):像“名字”“字段名”“编号”,用来定位
  • 值(value):这个键对应的内容

1.1 字典的基本写法

  • 花括号 {} 表示字典
  • 每一组“键—值”用 冒号 : 连接:键: 值
  • 多组之间用 逗号 , 分隔
person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

print(person)
# {'name': '小明', 'age': 18, 'city': '北京'}

上面这个字典里有 3 个键:

  • "name""小明"
  • "age"18
  • "city""北京"

注意:

  • 键通常用字符串,比如 "name""age",更直观。
  • 值可以是任意类型:数字、字符串、列表、字典、布尔值、None 等。

2. 键(key)与值(value)的规则

2.1 键的要求

在 Python 中:

  • 键必须是不可变类型,常见的有:
    • 字符串:"name"
    • 数字:12
    • 元组(里面也必须全是不可变的东西)
  • 不能用列表、字典等可变类型当键,否则会报错:
# 正确:字符串当键
data = {"a": 1, "b": 2}

# 正确:数字当键
data2 = {1: "一", 2: "二"}

# 错误:列表当键(会报 TypeError)
# bad = {["a", "b"]: 123}

新手阶段,你可以直接记住:

字典的键一般用字符串,就像字段名。

2.2 值的类型

值几乎可以是任何东西:

student = {
    "name": "小红",        # 字符串
    "age": 20,            # 整数
    "height": 1.65,       # 浮点数
    "is_graduated": False,# 布尔值
    "hobbies": ["唱歌", "画画"],  # 列表
    "scores": {           # 字典中嵌套字典
        "math": 95,
        "english": 88,
    },
}

3. 创建字典的几种方式

3.1 直接用大括号字面量(最常用)

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

3.2 用 dict() 函数创建

person = dict(name="小明", age=18)
print(person)  # {'name': '小明', 'age': 18}

注意:

  • 这种方式里,键必须是有效的变量名(不能有空格、不能以数字开头等),并且会自动当作字符串。
  • 大多数时候,还是推荐用 {},更直观。

3.3 先创建一个空字典

有时你暂时还不知道要放哪些键,只是先准备一个“空壳”,后面再逐步往里加键—值。

方法 1:用 {}

person = {}   # 空字典
print(person) # {}

方法 2:用 dict()

person = dict()
print(person) # {}

新手建议:

推荐用 {} 来创建空字典,简单清楚。


4. 访问字典中的值(非常重要)

4.1 用中括号访问:字典名[键]

基本格式:

字典名[键]

例子:

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

print(person["name"])  # 小明
print(person["age"])   # 18
print(person["city"])  # 北京

注意:

  • 键是字符串时,要写上引号:person["name"]不能写成 person[name](那是变量名)。
  • 如果访问一个不存在的键,会报 KeyError 错误:
# print(person["height"])  # KeyError: 'height'

4.2 使用 get() 访问值(更安全)

get() 是字典的一个方法:

字典.get(键, 默认值)
  • 如果键存在,返回对应的值;
  • 如果键不存在,返回你给的“默认值”(不写默认值则返回 None),不会报错

示例:

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

print(person.get("name"))        # 小明
print(person.get("city"))        # None(没有 city 这个键)
print(person.get("city", "未知"))# 未知(给了默认值)

新手记忆:

如果不确定键一定存在,推荐用 get(),避免 KeyError。


5. 添加键—值对 & 修改字典中的值

5.1 添加键—值对(直接赋值)

语法:

字典[新键] = 新值
  • 如果这个键不存在,就是添加新键—值对
  • 如果这个键已存在,就是修改这个键对应的值

例子:

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

# 添加一个新键 city
person["city"] = "北京"
print(person)
# {'name': '小明', 'age': 18, 'city': '北京'}

# 再添加一个键 hobby
person["hobby"] = "篮球"
print(person)
# {'name': '小明', 'age': 18, 'city': '北京', 'hobby': '篮球'}

5.2 修改已有键的值(也是用赋值)

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

person["age"] = 20      # 修改年龄
person["city"] = "上海" # 修改城市

print(person)
# {'name': '小明', 'age': 20, 'city': '上海'}

你可以看到:

添加和修改的语法是一样的:字典[键] = 值,区别在于这个键以前有没有存在。

5.3 先创建一个空字典,然后逐步添加

结合前面说的“空字典”,一个完整的例子:

person = {}  # 先创建空字典

person["name"] = "小红"
person["age"] = 19
person["city"] = "广州"

print(person)
# {'name': '小红', 'age': 19, 'city': '广州'}

这种写法很常见,比如你先问用户一大堆信息,然后依次塞进这个字典。


6. 删除键—值对

有几种方式可以删除字典中的键—值对。

6.1 使用 del 删除指定键

语法:

del 字典[键]

例子:

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

del person["city"]
print(person)
# {'name': '小明', 'age': 18}

注意:

  • 如果键不存在,del 会报 KeyError

6.2 使用 pop() 删除并返回值

语法:

值 = 字典.pop(键, 默认值)
  • 删除指定键,并返回它的值;
  • 如果键不存在:
    • 不写默认值:会报 KeyError
    • 写了默认值:返回默认值,不报错

例子:

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

age = person.pop("age")
print(age)     # 18
print(person)  # {'name': '小明'}

city = person.pop("city", "未知")
print(city)    # 未知
print(person)  # {'name': '小明'}

6.3 使用 popitem() 删除“最后一个添加的键—值对”

在 Python 3.7+ 中,字典是有插入顺序的,popitem() 会删除并返回“最后一个添加的键—值对”:

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

item = person.popitem()
print(item)    # ('city', '北京')
print(person)  # {'name': '小明', 'age': 18}

返回的是一个二元组 (键, 值)

6.4 使用 clear() 清空整个字典

person = {"name": "小明", "age": 18}
person.clear()
print(person)  # {}

7. 最后一个值为什么也可以加逗号?

你可能注意到我在写字典时,经常这样写:

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",   # 这里是“最后一行”,后面还是有逗号
}

问题:最后一行后面为什么也可以加逗号?

答案:这是 Python 语法允许的,主要是为了方便后期维护和修改代码

好处:

  • 以后你要在最后再加一行,不用再去上一行删逗号:
person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
    "hobby": "篮球",
}
  • 对比如果不允许最后一行加逗号:
    • 原来最后一行没有逗号
    • 你要插入一行时,得先给原本的“最后一行”加上逗号,再写新行,操作麻烦,还容易漏掉逗号导致语法错误

总结:

在字典(和列表、元组)中,最后一个元素后面写不写逗号都可以。
推荐风格:多行书写时,最后一项也保留一个逗号,更容易增删。


8. 字典的遍历(for 循环)

和列表一样,字典也可以用 for 遍历,但要注意:默认遍历的是“键”

8.1 遍历所有键(key)

person = {
    "name": "小明",
    "age": 18,
    "city": "北京",
}

for key in person:
    print("键:", key)

等价写法:

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

8.2 遍历所有值(value)

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

8.3 同时遍历键和值(最常用)

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

items() 返回的其实是一系列 (键, 值) 的小元组,for key, value in ... 可以一行解包。

输出示例:

name => 小明
age => 18
city => 北京

新手建议:

需要同时拿到键和值时,优先使用 for key, value in dict.items(),写得最清晰。


9. 字典的嵌套与复杂结构

字典很强大的一点是:值可以是列表、也可以是字典
这就可以构建非常灵活的数据结构,比如:

  • “列表中存字典”
  • “字典中存列表”
  • “字典中存字典”

下面分开讲。


10. 字典中存储列表

场景例子:一个人有多个爱好、多门课程成绩,列表就很适合放在字典里。

student = {
    "name": "小明",
    "age": 18,
    "hobbies": ["篮球", "吉他", "编程"],  # 列表
}

10.1 访问和遍历这个列表

print(student["hobbies"])
# ['篮球', '吉他', '编程']

for hobby in student["hobbies"]:
    print("爱好:", hobby)

输出:

爱好: 篮球
爱好: 吉他
爱好: 编程

10.2 添加列表元素

student["hobbies"].append("游泳")
print(student["hobbies"])
# ['篮球', '吉他', '编程', '游泳']

11. 字典中存储字典(嵌套字典)

场景例子:一个用户的“地址信息”又是一个结构化的内容(城市、街道、邮编等),很适合再用一个字典表示。

user = {
    "username": "xiaoming",
    "age": 18,
    "address": {
        "province": "北京",
        "city": "北京市",
        "district": "海淀区",
        "detail": "中关村大街 1 号",
    },
}

11.1 访问嵌套字典中的值

print(user["address"]["city"])    # 北京市
print(user["address"]["detail"])  # 中关村大街 1 号

理解方式:

  • user["address"] 先拿到“地址”这个子字典
  • 再对这个子字典用 ["city"]["detail"] 继续访问

11.2 遍历嵌套字典

for key, value in user["address"].items():
    print(key, "=>", value)

输出类似:

province => 北京
city => 北京市
district => 海淀区
detail => 中关村大街 1 号

12. 列表中存储字典(很多“记录”的列表)

在实际项目中,非常常见的一种结构是:

“列表中每一项都是一个字典”——可以理解成多条“记录”。

例如,一个班级有多名学生:

students = [
    {"name": "小明", "age": 18},
    {"name": "小红", "age": 19},
    {"name": "小刚", "age": 17},
]

12.1 遍历整个列表,访问每个字典

for student in students:
    print("姓名:", student["name"], "年龄:", student["age"])

输出:

姓名: 小明 年龄: 18
姓名: 小红 年龄: 19
姓名: 小刚 年龄: 17

12.2 结合条件判断

例如,打印所有年龄大于等于 18 的学生:

for student in students:
    if student["age"] >= 18:
        print(student["name"], "已成年")

13. 复杂一点的综合示例

综合使用“字典中存列表”“字典中存字典”“列表中存字典”:

class_info = {
    "name": "高一(1)班",
    "monitor": "小明",   # 班长
    "students": [        # 学生列表(列表中每个元素都是一个字典)
        {
            "name": "小明",
            "age": 16,
            "scores": {       # 字典中存字典
                "math": 95,
                "chinese": 88,
            },
        },
        {
            "name": "小红",
            "age": 15,
            "scores": {
                "math": 90,
                "chinese": 92,
            },
        },
    ],
}

13.1 遍历所有学生及成绩

print("班级名称:", class_info["name"])
print("班长:", class_info["monitor"])

for stu in class_info["students"]:
    name = stu["name"]
    age = stu["age"]
    math = stu["scores"]["math"]
    chinese = stu["scores"]["chinese"]

    print(f"姓名:{name},年龄:{age},数学:{math},语文:{chinese}")

你会发现,字典 + 列表的组合,可以很自然地表达现实中的各种结构化信息。


14. 字典的一些常用方法补充

14.1 keys() / values() / items()

前面已经用过,简单总结:

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

print(person.keys())    # dict_keys(['name', 'age'])
print(person.values())  # dict_values(['小明', 18])
print(person.items())   # dict_items([('name', '小明'), ('age', 18)])

一般配合 for 使用:

for key in person.keys():
    print(key)

for value in person.values():
    print(value)

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

14.2 in 判断键是否存在

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

print("name" in person)  # True
print("city" in person)  # False

if "city" not in person:
    print("还没有城市信息")

注意:in 检查的是,不是值。


15. 和列表一样,字典也有“长度”(len)

person = {"name": "小明", "age": 18, "city": "北京"}
print(len(person))  # 3(有 3 个键)

在遍历或判断是否为空时很常用:

if len(person) == 0:
    print("字典是空的")
else:
    print("字典里有数据")

16. 常见陷阱与小建议

16.1 KeyError:访问不存在的键

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

# print(person["age"])  # KeyError: 'age'

# 推荐用 get,避免报错
age = person.get("age", "未知")
print(age)  # 未知

16.2 键必须是不可变类型

# 错误示例:列表不能当键
# d = {["a", "b"]: 123}  # TypeError

16.3 字典是可变的,赋值是“引用同一个”

person1 = {"name": "小明"}
person2 = person1   # 两个变量指向同一个字典

person2["age"] = 18
print(person1)      # {'name': '小明', 'age': 18}
print(person2)      # {'name': '小明', 'age': 18}

如果想要复制一份新字典,用 copy()

person1 = {"name": "小明"}
person2 = person1.copy()

person2["age"] = 18
print(person1)   # {'name': '小明'}
print(person2)   # {'name': '小明', 'age': 18}

发表评论