前言

本文基于Python字典的五大核心知识点,结合英雄联盟英雄数据爬虫实战,带你一次掌握字典的所有常用操作。

一、为什么需要字典?

在Python中,列表(list)和元组(tuple)是通过索引(下标)来访问元素的,但索引是整数,且必须知道元素的位置。如果我们需要通过“名字”或“ID”来快速查找数据,列表就变得很不方便。

字典(dict) 应运而生,它采用 “键(key)- 值(value)” 的映射方式存储数据,就像一本真正的字典——通过拼音或偏旁(键)就能快速找到对应的释义(值)。

# 列表查找:需要知道下标
datas = [10, 20, 30, 40, 50]
print(datas[2])   # 30

# 字典查找:通过有意义的键
person = {"name": "马化腾", "id": 101, "age": 50}
print(person["name"])   # 马化腾

二、字典的定义与基本特性

2.1 创建字典

字典使用 花括号 {} 定义,键和值用冒号 : 分隔,键值对之间用逗号分隔。

# 空字典
d0 = {}
print(type(d0))  # <class 'dict'>

# 直接创建
d1 = {
    "id": 101,
    "name": "马化腾",
    "info": "腾讯创始人"
}
print(d1)

# 使用 dict() 转换:传入一个可迭代对象,其中每个元素是包含两个值的子序列
d2 = dict((["id", 101], ("name", "马化腾")))
print(d2)  # {'id': 101, 'name': '马化腾'}

2.2 字典的核心特性

键必须唯一:如果多次赋值相同的键,后面的会覆盖前面的。

键必须是不可变类型:如整数、浮点数、字符串、布尔值、元组(注意:列表、字典不能作为键)。

值可以是任意类型:包括列表、字典、甚至自定义对象。

d = {
    1: 2,                 # 整数键
    0: 123,
    True: 666,            # 布尔值也是整数,True 等同于 1,会覆盖键 1 的值
    False: 888,
    3.15: 3.14,           # 浮点数
    "key1": 100,          # 字符串
    None: 456,            # None 作为键
    (1,): 789,            # 元组(不可变)
    # []: 963,            # ❌ 列表可变,不能作为键
    # {}: 741,            # ❌ 字典可变,不能作为键
}
print(d)
# 输出:{1: 666, 0: 888, 3.15: 3.14, 'key1': 100, None: 456, (1,): 789}
# 注意:True 和 1 被视为同一个键,False 和 0 也被视为同一个键。

2.3 字典的嵌套

字典的值可以是另一个字典,形成任意深度的嵌套结构,非常适合表示复杂的JSON数据。

d = {
    "key8": {
        "key81": 666,
        "key82": {
            "key821": 888,
            "key822": [
                {"id": 101, "name": "马云"},
                {"id": 102, "name": "马化腾"}
            ]
        }
    }
}
# 访问深层数据
print(d['key8']['key82']['key822'][-1]['name'])  # 马化腾

三、字典的遍历

3.1 遍历键

d = {"id": 101, "age": 20, "name": "马云"}
for k in d.keys():
    print(k, d[k])
# 或者直接 for k in d:

3.2 遍历值

for v in d.values():
    print(v)
注意:字典是无序的(Python 3.6+ 会保持插入顺序,但不应依赖),因此不能通过值反查键(除非遍历全部值)。

3.3 同时遍历键和值(items)

for k, v in d.items():
    print(k, v)

四、字典的常见操作

4.1 添加与修改

d = {"id": 100}
d["name"] = "马云"    # 新增键
d["id"] = 101         # 修改已有键

4.2 获取值(get)

使用 get(key, default) 可以安全获取值,键不存在时返回 default(默认为 None),避免 KeyError。

print(d.get("age", 5))   # 5
print(d.get("name"))     # 马云

4.3 删除元素

pop(key):删除指定键并返回其值,若键不存在则抛出异常(可传入第二个参数避免)。

popitem():删除并返回最后一个插入的键值对(Python 3.7+)。

clear():清空整个字典。

del d[key]:删除指定键(不返回值)。

d = {"id": 100, "name": "马云", "age": 20}
v = d.pop("age")        # 20
last = d.popitem()      # ('name', '马云')
d.clear()               # {}

4.4 setdefault

如果键存在,则返回原值且不修改;如果键不存在,则设置新值并返回。

d = {"addr": "郑州"}
d.setdefault("addr", "杭州")   # 已存在,不修改
print(d)  # {'addr': '郑州'}
d.setdefault("city", "北京")   # 新增
print(d)  # {'addr': '郑州', 'city': '北京'}

4.5 update 合并字典

将另一个字典的所有键值对合并到当前字典,相同键会被覆盖。

d.update({"info": "企业家", "sex": "男"})

4.6 fromkeys 批量创建

使用类方法 dict.fromkeys(iterable, value) 创建一个新字典,所有键来自可迭代对象,值统一为 value。

d = dict.fromkeys(["key1", "key2", "key3"], 888)
print(d)  # {'key1': 888, 'key2': 888, 'key3': 888}

五、实战案例:统计字符出现次数

题目:统计字符串 “hello world” 中每个字符出现的次数。

方案一(传统判断):

d = {}
s = "hello world"
for c in s:
    if c in d:
        d[c] += 1
    else:
        d[c] = 1
print(d)

方案二(利用 get 简化):

d = {}
for c in s:
    d[c] = d.get(c, 0) + 1
print(d)
输出:{'h':1, 'e':1, 'l':3, 'o':2, ' ':1, 'w':1, 'r':1, 'd':1}

六、高级实战:爬取LOL英雄数据并进行分析

我们使用 requests 库请求官方英雄列表接口,然后利用字典操作完成几个小题目。

6.1 安装与请求

import requests

url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js?ts=2974219'
res = requests.get(url)
heros = res.json()['hero']   # 直接解析JSON,得到英雄列表(每个英雄是一个字典)
print(f"共有 {len(heros)} 个英雄")

6.2 遍历每个英雄的部分信息

f

or hero in heros:
    print(hero['name'], hero['isWeekFree'], hero['isARAMweekfree'], hero['magic'])

6.3 求操作难度最大的英雄

max_difficulty_hero = heros[0]
for hero in heros[1:]:
    if int(hero['difficulty']) > int(max_difficulty_hero['difficulty']):
        max_difficulty_hero = hero
print(f"最难操作的英雄:{max_difficulty_hero['name']}(难度 {max_difficulty_hero['difficulty']})")

6.4 统计神枪手(射手)的数量

marksman_list = [hero for hero in heros if 'marksman' in hero['roles']]
print(f"神枪手(射手)共有 {len(marksman_list)} 个")

七、JSON序列化与反序列化

在实际开发中,我们经常需要将Python字典保存为文件或通过网络传输,JSON(JavaScript Object Notation)是最通用的格式。

7.1 序列化:Python字典 → JSON字符串

json.dumps():转为字符串。

json.dump():直接写入文件。

import json

students = [
    {"id": 101, "name": "张飞"},
    {"id": 102, "name": "赵云"},
    {"id": 103, "name": "关羽"}
]
# 转为字符串(保留中文)
students_str = json.dumps(students, ensure_ascii=False)
print(students_str)
# 写入文件
with open("data.txt", "w", encoding="utf-8") as f:
    json.dump(students, f, ensure_ascii=False)
7.2 反序列化:JSON字符串 → Python字典
json.loads():从字符串解析。

json.load():从文件对象解析。
# 从文件读取并解析
with open("data.txt", "r", encoding="utf-8") as f:
    students_loaded = json.load(f)
    print(students_loaded[0]["name"])   # 张飞

总结

极速查找 :基于哈希表,增删改查平均时间复杂度 O(1),百万数据毫秒级定位。

极度灵活 :键可以是字符串、数字、元组等不可变类型,值可以是任意对象(列表、字典、函数等),轻松表达复杂嵌套数据。

极其方便 :内置 get、setdefault、update、pop、fromkeys 等丰富方法,一行代码搞定安全取值、合并、删除,编码简洁又健壮。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐