4. 序列遍历技巧:for循环遍历、enumerate()获取索引、zip()并行遍历

遍历序列,说白了就是挨个儿访问里面的元素。这事儿看起来简单,但写得好不好,直接关系到代码的优雅程度和坑的数量。我见过不少新手,甚至有些老手,在遍历上栽过跟头。

今天咱们就把这三种核心遍历方式掰开揉碎,讲清楚。

4.1 for循环遍历:最基础的玩法

for 循环是 Python 里遍历序列的标配。你想想看,一个列表、元组、字符串,甚至字典,都能用 for 直接撸一遍。

fruits = ['苹果', '香蕉', '橘子', '葡萄']
for fruit in fruits:
    print(fruit)

输出很简单:

苹果
香蕉
橘子
葡萄

我个人习惯,只要不需要索引,优先用这种直接遍历。代码干净,读起来也舒服。

小提示: 遍历字符串时,每个字符都会被单独取出。如果你需要处理文本中的每个字,for char in text 是最直接的方式。

4.2 enumerate()获取索引:既要元素又要位置

很多时候,我们不光要元素,还得知道它在序列里的位置。比如你要修改列表里的某些项,或者记录每个元素的下标。

新手常犯的错误是这么写:

fruits = ['苹果', '香蕉', '橘子', '葡萄']
for i in range(len(fruits)):
    print(i, fruits[i])

嗯,这代码能跑,但不够 Pythonic。每次都要 range(len(...)),看着就啰嗦。

更好的做法是用 enumerate():

for i, fruit in enumerate(fruits):
    print(i, fruit)

输出:

0 苹果
1 香蕉
2 橘子
3 葡萄

我曾经在一个数据处理项目里,需要同时记录每行数据的行号和内容。一开始用的 range(len()),后来改成 enumerate(),代码量直接减半,可读性也上去了。

核心要点: enumerate() 默认从 0 开始计数。如果你希望从 1 开始,可以传第二个参数:enumerate(fruits, start=1)。

4.3 zip()并行遍历:同时处理多个序列

有时候,你需要同时遍历两个或多个序列。比如你有两个列表,一个存名字,一个存分数,你想把它们一一对应地打印出来。

没有 zip() 的时候,你可能得这么写:

names = ['张三', '李四', '王五']
scores = [85, 92, 78]
for i in range(len(names)):
    print(names[i], scores[i])

这代码有个隐患——如果两个列表长度不一样,就会报索引越界的错。我踩过这个坑,当时排查了半天才发现是数据源出了问题。

用 zip() 就安全多了:

for name, score in zip(names, scores):
    print(name, score)

输出:

张三 85
李四 92
王五 78

zip() 会以最短的序列为准,自动截断。这既是优点也是坑——如果你没意识到数据长度不一致,可能会悄无声息地丢掉数据。

避坑指南: 我曾经在合并两个 CSV 文件时用了 zip(),结果因为其中一个文件少了一行,导致最后一条数据被静默丢弃。后来我养成了一个习惯:在 zip() 之前,先检查两个序列的长度是否一致。

4.4 三种遍历方式的对比

方式 适用场景 优点 缺点
for item in seq 只需要元素,不需要索引 代码最简洁,可读性最高 无法获取元素位置
enumerate(seq) 需要元素和索引 比 range(len()) 更优雅 稍微多一层解包
zip(seq1, seq2) 同时遍历多个序列 自动对齐,代码简洁 以最短序列为准,可能丢数据

4.5 组合使用:enumerate() + zip()

这两个函数还能组合使用。比如你有三个列表,既要并行遍历,又要记录索引:

names = ['张三', '李四', '王五']
scores = [85, 92, 78]
grades = ['B', 'A', 'C']

for i, (name, score, grade) in enumerate(zip(names, scores, grades)):
    print(f'{i}: {name} - {score}分 - {grade}等级')

输出:

0: 张三 - 85分 - B等级
1: 李四 - 92分 - A等级
2: 王五 - 78分 - C等级

这里要注意括号的嵌套顺序。我刚开始用的时候也经常搞混,多写几次就习惯了。

实战建议: 在数据处理、日志分析、批量文件操作等场景中,enumerate() 和 zip() 的组合几乎是标配。掌握它们,能让你的代码从「能跑」变成「漂亮」。

4.6 知识结构图

下面这张图帮你理清这三种遍历方式的关系和适用场景:

序列遍历技巧知识结构 序列遍历 for item in seq enumerate(seq) zip(seq1, seq2) 适用场景 只需元素,不要索引 代码最简洁 适用场景 需要元素+索引 比range(len())更优雅 适用场景 同时遍历多个序列 注意长度不一致问题 组合:enumerate(zip(seq1, seq2))

4.7 实战避坑总结

  • 别滥用 range(len())——能用 enumerate() 就别手写索引循环。
  • zip() 会静默截断——如果两个序列长度不一致,短的说了算。提前检查长度是个好习惯。
  • 嵌套解包注意括号——enumerate(zip(...)) 的括号顺序别搞反了。
  • 遍历字典时——默认遍历的是键。如果需要键值对,用 .items()。

这三种遍历技巧,说白了就是 Python 给咱们准备的「三板斧」。用好了,代码既简洁又高效。我建议你平时写代码时,有意识地用 enumerate() 和 zip() 替代那些老套的写法,慢慢就形成肌肉记忆了。