Python中使用enumerate优雅地遍历序列及索引

34次阅读
没有评论

共计 1624 个字符,预计需要花费 5 分钟才能阅读完成。

在 Python 中,很多时候我们需要遍历一个序列的同时获取每个元素的索引。很多初学者会这样做:

fruits = ['apple', 'banana', 'cherry']
for i in range(len(fruits)):
    print(i, fruits[i])

虽然这段代码可以正常运行,但是并不是 Pythonic 的写法,代码显得冗长而不直观。更推荐的写法是使用 enumerate() 函数。

一、什么是 enumerate?

enumerate()是 Python 内置函数,它将一个可迭代对象(如列表、元组或字符串)组合为一个索引序列,同时返回索引和对应的值。它的语法如下:

enumerate(iterable, start=0)
  • iterable:任何可迭代对象;
  • start:索引起始值,默认为 0。

来看一个简单示例:

fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
    print(index, fruit)

输出为:

0 apple
1 banana
2 cherry

这样写的好处在于:

  • 不需要手动使用 range()len()
  • 可读性更高;
  • 代码更简洁优雅。

二、设置自定义起始索引

如果你不想从 0 开始索引,比如你想从 1 开始,也非常简单,只需要设置 start 参数:

for index, fruit in enumerate(fruits, start=1):
    print(index, fruit)

输出为:

1 apple
2 banana
3 cherry

这在处理用户列表、菜单、表格等具有自然编号场景中非常实用。

三、与字典组合使用

假设你有一个学生列表,需要自动生成编号,可以这样使用enumerate

students = ['Tom', 'Lucy', 'Jack']
student_dict = {i: name for i, name in enumerate(students, start=1)}
print(student_dict)

输出:

{1: 'Tom', 2: 'Lucy', 3: 'Jack'}

四、和 zip 的对比

有人可能会问,zip(range(len(fruits)), fruits)enumerate(fruits) 有什么区别?来看示例:

for i, fruit in zip(range(len(fruits)), fruits):
    print(i, fruit)

虽然也能达到相同目的,但 enumerate() 更语义清晰、性能更优。zip()会先将两个对象组合为新的可迭代对象,而 enumerate() 是专门为这种“需要索引”的场景设计的。

五、避免使用反模式

反模式如下:

i = 0
for fruit in fruits:
    print(i, fruit)
    i += 1

虽然这段代码看起来没什么问题,但它:

  • 多了一个外部变量i
  • 需要手动维护 i 的增量;
  • 容易引起出错或混乱。

这种写法不符合 Python 的设计哲学“优雅”、“简洁”、“明确”。

六、enumerate 处理嵌套循环

enumerate()也可以配合嵌套列表处理二维结构。比如:

matrix = [[1, 2],
    [3, 4],
    [5, 6]
]

for row_index, row in enumerate(matrix):
    for col_index, value in enumerate(row):
        print(f'[{row_index}, {col_index}] = {value}')

输出为:

[0, 0] = 1
[0, 1] = 2
[1, 0] = 3
[1, 1] = 4
[2, 0] = 5
[2, 1] = 6

这在处理表格、图像、地图等二维数据时非常有用。

七、小结

  • enumerate() 是获取元素索引和内容的首选方法;
  • 它比 range(len(...)) 更清晰、更安全;
  • 支持自定义起始索引;
  • 可用于字典生成、嵌套结构等复杂场景。

建议从今天起,逐步将涉及索引遍历的代码改写为 enumerate() 风格,你会发现代码更易读、也更优雅。

掌握 enumerate() 是迈向 Python 高级用法的重要一步。

正文完
 0
评论(没有评论)