Python for循环遍历字典键、值及键值对的三种方式

陈默
陈默
发布时间:2026-11-10| 12人浏览过
原创

系统解析Python中使用for循环遍历字典的三种核心方式:遍历键、遍历值以及同时遍历键值对,包含底层机制解析、代码示例、元组解包及遍历中修改字典的避坑指南。

在 Python 中,字典(dict)由键与值的对应关系构成。使用 for 循环操作字典时,实际需求通常划分为三类:只需处理键、只需处理值,或需要键与值同步参与逻辑。针对这三类场景,Python 提供了三种直接的迭代方式:默认或显式遍历键(.keys())、遍历值集合(.values()),以及借助元组解包同时遍历键与值(.items())。
Python for循环遍历字典键、值及键值对的三种方式
Python 字典遍历的三种核心技术路径概览

一、字典在 Python 中的迭代特性

Python 字典是基于哈希表实现的键值映射容器。在 Python 3.7 及更高版本中,字典不仅具备常数级时间复杂度的查找性能,还保证了元素插入顺序的确定性。

对字典调用迭代方法时,返回的并非静态列表副本,而是动态的字典视图对象(Dictionary View Objects),包括 dict_keys、dict_values 和 dict_items。这些视图对象提供了对底层字典数据的只读迭代接口,当底层字典内容变更时,视图所反映的数据会动态更新。

Python for循环遍历字典键、值及键值对的三种方式
图 1:Python 字典内部结构与三种迭代视图 (View Objects) 映射关系

二、方式一:遍历字典的键(Keys)

当业务逻辑仅需要检查键的存在性、统计键集合,或者需要按照键名依次检索时,应当遍历字典的键。获取键有两种常见书写方式。

1. 直接遍历字典对象(推荐写法)

在 Python 语法中,字典本身就是一个可迭代对象,其默认的迭代器行为就是产生键名。这是最符合 Python 习惯(Pythonic)的紧凑写法:

# 示例字典:各学科的考评学分
course_credits = {
    "Calculus": 4,
    "Linear Algebra": 3,
    "Data Structure": 4,
    "Computer Network": 3
}

# 直接遍历字典,循环变量每次获取一个键
for course in course_credits:
    print(f"课程名称: {course}")
示例输出
课程名称: Calculus
课程名称: Linear Algebra
课程名称: Data Structure
课程名称: Computer Network

2. 显式调用 dict.keys() 方法

也可以通过显式调用 course_credits.keys() 达到相同的遍历效果:

for course in course_credits.keys():
    print(f"课程名称: {course}")

何时显式使用 .keys()? 从循环迭代效率来看,两种写法完全相同。显式调用 .keys() 的主要价值在于表达明确的编码意图,或者需要对键视图执行集合操作(如交集 keys() & other_dict.keys()、差集等运算)时。在普通的 for 循环中,直接写 for key in d: 更加简洁明了。

三、方式二:遍历字典的值(Values)

当业务处理完全围绕数值指标展开,无需反查是哪一个键拥有该数值时(例如数值求和、计算平均值、寻找最值或状态判定),应当使用 dict.values() 方法。

# 示例字典:某服务器连续五分钟的内存使用率 (百分比)
mem_usage_samples = {
    "10:01": 68.5,
    "10:02": 72.1,
    "10:03": 75.4,
    "10:04": 81.0,
    "10:05": 78.2
}

total_usage = 0.0
sample_count = 0

# 仅遍历内存数值,忽略时间戳键
for usage in mem_usage_samples.values():
    total_usage += usage
    sample_count += 1

average_usage = total_usage / sample_count
print(f"采样点总数: {sample_count}")
print(f"平均内存使用率: {average_usage:.2f}%")
示例输出
采样点总数: 5
平均内存使用率: 75.04%

性能注意点: 如果此时采用 for k in d: total += d[k],每一次循环都需要对 k 进行一次哈希运算与桶查找;而 d.values() 直接从哈希表中提取值指针,避免了二次索引寻址,执行更加高效。

四、方式三:同时遍历键与值(Key-Value 对)

在需要将属性名与具体数值关联输出、格式化报表,或根据数值条件筛选特定键时,同时获取键与值是最高频的操作模式。Python 提供了 dict.items() 方法。

1. 元组解包语法与机制

dict.items() 在每次迭代时产出一个形如 (key, value) 的二元元组。利用 Python 内建的序列解包特性,可以在 for 语句头部直接定义两个变量分别接收键和值:

# 示例字典:微服务健康状态检查
service_status = {
    "auth-api": "UP",
    "payment-gateway": "UP",
    "order-service": "DOWN",
    "notification-worker": "UP"
}

# 使用 key, value 接收解包结果
for service_name, status in service_status.items():
    indicator = "正常" if status == "UP" else "异常"
    print(f"服务 [{service_name}] 运行状态: {indicator}")
示例输出
服务 [auth-api] 运行状态: 正常
服务 [payment-gateway] 运行状态: 正常
服务 [order-service] 运行状态: 异常
服务 [notification-worker] 运行状态: 正常
Python for循环遍历字典键、值及键值对的三种方式
图 2:for key, value in d.items() 的序列解包分步执行流程

2. 对比反模式:为什么不要用 d[key] 二次查找

初学者容易写出如下形式的代码:

# 不推荐的反模式代码
for key in service_status:
    value = service_status[key]  # 冗余的二次哈希查找
    print(key, value)

这种写法存在两个明显缺陷:其一,代码可读性较差,每次都需要手动索引;其二,service_status[key] 会强制 Python 重新在字典哈希表中进行键哈希计算与冲突比对。而 service_status.items() 直接在单次遍历中一并提供键与值,无论在代码优雅度还是在执行效率上都明显更优。

五、避坑指南:遍历中修改字典引发的异常与安全方案

在遍历字典时,一个极为普遍的错误是在循环体内部增加或删除字典项。

Python for循环遍历字典键、值及键值对的三种方式
图 3:遍历时动态修改字典的报错原理与两种安全解决方案

1. 故障表现与触发根因

尝试在遍历过程中删除不合格项:

# 错误示例代码:在迭代中删除元素
stock_levels = {"apple": 15, "banana": 0, "orange": 8, "pear": 0}

for fruit in stock_levels:
    if stock_levels[fruit] == 0:
        del stock_levels[fruit]  # 触发 RuntimeError
实际执行报错示例
RuntimeError: dictionary changed size during iteration

原因分析: Python 字典底层维护了一个内部版本计数器(ma_version_tag)。当迭代器创建时,它会记录当下的版本号。在单次迭代步进时,如果检测到底层字典的长度发生改变(无论是 del、pop() 还是新增键值),迭代器为了避免因哈希表重排导致漏读或死循环,会主动抛出 RuntimeError 中断执行。

2. 安全修复方案 A:通过 list() 制造静态键快照

如果确实需要在原字典上就地执行删除,可以使用 list() 函数先将键转换为一个独立的列表快照,遍历该快照列表:

stock_levels = {"apple": 15, "banana": 0, "orange": 8, "pear": 0}

# 通过 list() 固化键的副本,循环迭代的是独立的列表,原字典的修改不会影响该列表
for fruit in list(stock_levels.keys()):
    if stock_levels[fruit] == 0:
        del stock_levels[fruit]

print("清理后的库存:", stock_levels)
示例输出
清理后的库存: {'apple': 15, 'orange': 8}

3. 安全修复方案 B:使用字典推导式重构(推荐)

在函数式编程或现代 Python 实践中,更倡导生成新数据对象而非就地改变原状态。字典推导式能够用一行代码完成过滤:

stock_levels = {"apple": 15, "banana": 0, "orange": 8, "pear": 0}

# 纯函数式生成新字典,逻辑清晰且无副作用
valid_stocks = {fruit: qty for fruit, qty in stock_levels.items() if qty > 0}

print("过滤后的有效库存:", valid_stocks)
示例输出
过滤后的有效库存: {'apple': 15, 'orange': 8}

六、三种遍历方式的对比与选型决策

下表汇总了三种遍历方式的语法、返回值类型、变量绑定形式与适用场景:

遍历目标 标准语法 底层视图类型 每次循环产物 典型适用场景
仅遍历键 for k in d: dict_keys 单个键对象 (Key) 仅检查属性名、提取键列表、校验存在性
仅遍历值 for v in d.values(): dict_values 单个值对象 (Value) 数值求和、平均值统计、找最值,无需反查键名
同时遍历键与值 for k, v in d.items(): dict_items 二元元组解包 (k, v) 格式化打印输出、按值筛选键、字典重构与序列化
Python for循环遍历字典键、值及键值对的三种方式
图 4:Python 字典 for 循环遍历方式快速选型决策树与场景总结
工程选型准则

在编写字典遍历逻辑时,遵循“按需索取”原则:只用键就写 for k in d:;只用值就写 for v in d.values():;两者都用务必使用 for k, v in d.items():,坚决避免在仅获取键的循环中反复使用 d[k] 索引访问。

相关专题:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。