应优先使用 enumerate() 而非 range(len()),因其兼容生成器、迭代器且更安全;支持 start 参数设起始索引(须为整数);嵌套循环需内外层均使用 enumerate() 避免索引错位。

直接用 enumerate() 就行,它专为这个场景设计,比手动维护计数器更安全、更 Pythonic。
为什么不能用 range(len()) 配合索引访问?
常见错误是写成 for i in range(len(items)): print(i, items[i]) —— 看似可行,但遇到生成器、迭代器(比如 map() 或文件对象)会直接报错:TypeError: object of type 'map' has no len()。而 enumerate() 只要求对象可迭代,兼容性更强。
- 列表、元组、字符串:完全支持
- 生成器、
zip()、文件句柄:也支持,且不提前耗尽迭代器 - 空迭代:返回空结果,不会报错
enumerate() 的起始索引怎么设?
默认从 0 开始,但经常需要从 1 开始(比如打印带序号的菜单),这时传入 start 参数即可:
fruits = ['apple', 'banana', 'cherry']
for i, fruit in enumerate(fruits, start=1):
print(f"{i}. {fruit}")
# 输出:
# 1. apple
# 2. banana
# 3. cherry
-
start必须是整数,支持负数(如start=-1) - 不支持浮点数,否则抛
TypeError: 'float' object cannot be interpreted as an integer - 如果只是想跳过前几个元素,优先用切片(
enumerate(items[2:])),而非调大start,否则索引和原始位置对不上
嵌套循环里用 enumerate() 容易漏掉哪层?
二维结构(如列表的列表)中,常有人只在外层用 enumerate(),却忘了内层也要用,导致“索引错位”:
matrix = [[1, 2], [3, 4]]
# ❌ 错误:内层用普通 for,i 是外层索引,j 是值,不是内层索引
for i, row in enumerate(matrix):
for j in row:
print(f"({i},{j}) = {j}") # j 是值,不是列索引!
<h1>✅ 正确:内外都用 enumerate</h1><p>for i, row in enumerate(matrix):
for j, val in enumerate(row):
print(f"({i},{j}) = {val}")
</p>
- 内层不加
enumerate()时,j是元素值,不是下标 —— 这是最常见的逻辑混淆点 - 如果只需要某一层索引,明确注释意图,避免后续维护者误读
- 对性能敏感场景(如超大矩阵),
enumerate()开销极小,不必为这点微优化牺牲可读性
真正要注意的是:别把 enumerate() 当成“加序号工具”硬套在非迭代场景里,比如对单个数字或字典键值对乱用;它的本质是包装迭代器,核心价值在于解耦索引与遍历逻辑 —— 这一点,手写计数器永远做不到。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











