查看全课大纲(第 48 / 51 节)
  1. 1.Python 是什么?为什么值得学?
  2. 2.如何为 Python 编程准备一个“全家桶”环境?
  3. 3.Python 有哪几种执行方法?
  4. 4.行与缩进到底有什么用?
  5. 5.注释有什么用,怎么写?
  6. 6.变量:如何给数据起个好名字?
  7. 7.运算符的优先级和常见坑点是什么?
  8. 8.Python 中,数字和布尔值究竟有哪几种?
  9. 9.输入函数 `input()` 和文件读取 `open()` 怎么用?
  10. 10.如何将程序的结果展示给用户或保存下来?
  11. 11.CSV 文件怎么读怎么写才方便?
  12. 12.列表是什么,如何创建和访问它?
  13. 13.列表的修改操作,有哪些方法?
  14. 14.列表切片为什么能取到部分元素?排序和查找又该怎么用?
  15. 15.判断语句:如何让程序根据条件做不同的事?
  16. 16.for 循环如何遍历序列中的元素?
  17. 17.while 循环什么时候才会停?
  18. 18.while 循环的结束条件,你写对了吗?
  19. 19.循环中途想提前结束,怎么办?
  20. 20.`break` 和 `continue` 到底有什么区别?
  21. 21.列表推导式如何让代码更简洁高效?
  22. 22.字符串怎么定义、拼接和操作?
  23. 23.元组:为什么定义单个元素时要加逗号?
  24. 24.集合(set)怎么用?如何快速去重和做集合运算?
  25. 25.字典是什么,为什么比列表更方便?
  26. 26.字典的增删改查与遍历,如何避免 KeyError?
  27. 27.函数里的变量,为什么有的能用有的不能用?
  28. 28.在函数内部修改全局变量,为什么有时不生效?
  29. 29.函数里能修改全局变量吗?返回值怎么用?
  30. 30.匿名函数:如何用 lambda 快速定义简单函数?
  31. 31.面向对象编程是什么,为什么需要它?
  32. 32.类中的方法和属性到底怎么定义和使用?
  33. 33.如何控制对对象内部属性和方法的访问?
  34. 34.异常发生时,程序会怎样继续执行?
  35. 35.如何组织代码:包和模块
  36. 36.`if __name__ == '__main__'` 到底有什么用?
  37. 37.如何用 IDE 的 Debug 功能排查程序错误?
  38. 38.Matplotlib 绘图的第一步该做什么?
  39. 39.Figure 是什么,如何设置图形尺寸?
  40. 40.如何自定义 Matplotlib 的坐标轴?
  41. 41.如何为图表添加图例,让不同曲线一目了然?
  42. 42.饼图怎么画才能直观展示数据占比?
  43. 43.如何用 Matplotlib 绘制散点图?
  44. 44.柱状图怎么画?
  45. 45.如何使用 Matplotlib 绘制等高线图?
  46. 46.如何在 Matplotlib 中绘制子图?
  47. 47.zip 函数如何把多个列表“打包”在一起?
  48. 48.如何给可迭代对象加上索引?
  49. 49.random 模块如何生成随机数?
  50. 50.math 模块怎么用?
  51. 51.Counter 如何快速统计元素出现次数?

如何给可迭代对象加上索引?

约 5 分钟

小象实战讲义 · Python 编程从入门到实践

在编程中,我们经常需要同时拿到序列中的元素和它的位置。列表还可以靠下标访问,但集合(set)根本没有下标;即使是列表,在遍历时手动维护一个索引变量也略显繁琐。本节讲解 enumerate 函数,它能把可遍历的数据对象组合成带索引的序列,让你在 for 循环里一次拿到索引和元素。本节是第 6 章《一些常用的函数》的第 2 节。

💡 核心导读

  • 是什么:enumerate 把一个可遍历的数据对象(列表、元组、集合等)组合成带索引的序列。
  • 语法:enumerate(sequence, start=0),start 指定索引的起始值。
  • 返回值:一个 enumerate 对象,可以转成列表查看,也可以直接在 for 循环中使用。
  • 典型场景:遍历集合(无下标)时获取序号,或遍历列表时省掉手动维护的索引变量。
  • 注意点:集合没有下标,enumerate 给遍历到的元素依次编号。

基本语法与作用

enumerate 的作用是把数据和数据的下标对应起来,语法格式如下:

enumerate(sequence, start=0)
  • sequence:一个可遍历的数据对象,如列表、元组、集合等。
  • start:可选参数,索引从哪个数字开始数,默认是 0。
  • 返回值:一个 enumerate 对象。它可以直接用于 for 循环,也可以转成列表查看内容。

集合没有下标,无法用 names[0] 这种方式访问元素。下面的例子用 enumerate 给集合中的元素编号:

# 集合没有下标,用 enumerate 给它加上编号
names = {'Mike', 'Jenny', 'Sophia', 'John'}

enum_obj = enumerate(sorted(names))  # 集合无序,先排序让输出稳定
print(type(enum_obj))
print(list(enum_obj))

# start 参数:指定索引从 1 开始
print(list(enumerate(sorted(names), start=1)))
<class 'enumerate'>
[(0, 'Jenny'), (1, 'John'), (2, 'Mike'), (3, 'Sophia')]
[(1, 'Jenny'), (2, 'John'), (3, 'Mike'), (4, 'Sophia')]

转换后的列表里,每个元素都是 (索引, 元素值) 形式的元组。这里先对集合做了 sorted(),只是为了让打印结果稳定、便于对照。

在 for 循环中使用 enumerate

enumerate 最常见的用法是在 for 循环中同时取得索引和值。循环变量写两个,分别接收元组里的索引和元素:

names = {'Mike', 'Jenny', 'Sophia', 'John'}

# 默认从 0 开始编号
for index, name in enumerate(sorted(names)):
    print(index, name)

print('---')
# 也可以从 1 开始编号
for index, name in enumerate(sorted(names), start=1):
    print(index, name)
0 Jenny
1 John
2 Mike
3 Sophia
---
1 Jenny
2 John
3 Mike
4 Sophia

for index, name in enumerate(names): 这一行做了两件事:enumerate(names) 每轮产出一个 (索引, 元素) 元组,index, name 再把元组拆开,分别赋值给两个变量。

对比:手动维护索引 vs 使用 enumerate

假设要在打印列表元素时一并打印下标。不用 enumerate 的话,常见的做法是自己维护一个计数器:

names_list = ['Mike', 'Jenny', 'Sophia', 'John']

# 手动维护索引
i = 0
for name in names_list:
    print('第{}个名字是:{}'.format(i, name))
    i += 1

print('--- 用 enumerate 的写法 ---')
# 交给 enumerate 维护索引,代码更短
for i, name in enumerate(names_list):
    print('第{}个名字是:{}'.format(i, name))
第0个名字是:Mike
第1个名字是:Jenny
第2个名字是:Sophia
第3个名字是:John
--- 用 enumerate 的写法 ---
第0个名字是:Mike
第1个名字是:Jenny
第2个名字是:Sophia
第3个名字是:John

两种写法输出一致,但手动维护需要额外两行代码来初始化和更新 i,而 enumerate 直接表达“遍历带索引的列表”,意图更清晰。

📝 动手练一练

  1. 有一个水果集合 fruits = {'apple', 'banana', 'orange'},请用 enumerate 从数字 10 开始编号,并把结果转成列表打印。
👉 点击查看参考答案

思路:enumerate(fruits, start=10) 从 10 开始编号,再转成列表。集合无序,为了让输出可对照,先 sorted() 再编号。

fruits = {'apple', 'banana', 'orange'}
numbered_fruits = list(enumerate(sorted(fruits), start=10))
print(numbered_fruits)
[(10, 'apple'), (11, 'banana'), (12, 'orange')]
  1. 遍历列表 colors = ['red', 'green', 'blue'],用 enumerate 打印 1: red 这样的格式(索引从 1 开始)。
👉 点击查看参考答案

思路:在 for 循环中使用 enumerate(colors, start=1),同时接住索引和颜色。

colors = ['red', 'green', 'blue']
for idx, color in enumerate(colors, start=1):
    print('{}: {}'.format(idx, color))
1: red
2: green
3: blue

常见错误

错误写法现象或报错原因正确写法
print(enumerate(names))输出类似 <enumerate object at 0x...>enumerate 返回的是对象,不直接显示内容print(list(enumerate(names)))
以为 enumerate(集合) 的输出顺序固定换一次运行,元素顺序可能不同集合本身无序,enumerate 只按当前遍历顺序编号需要固定顺序时先排序:enumerate(sorted(my_set))
需要从 1 开始编号却忘了 start编号从 0 开始,与预期差 1默认 start=0enumerate(seq, start=1)

小结

  1. enumerate(sequence, start=0) 给可迭代对象加上索引,生成 (索引, 元素) 对。
  2. 索引起始值由 start 参数决定,默认是 0。
  3. 返回值是 enumerate 对象,可转成列表查看,也常直接在 for 循环中迭代。
  4. for i, value in enumerate(seq): 能同时拿到索引和值,比手动维护索引变量更简洁。
  5. 对集合使用 enumerate 时,编号跟随遍历到的元素依次生成。

📋 行动清单

  • 把示例中的 start=1 改成 start=100,重新运行,观察编号变化。
  • 对同一个集合分别执行 list(enumerate(names)) 和 list(enumerate(sorted(names))),比较输出顺序。
  • 把“手动维护索引”的写法改写成 enumerate 写法,确认输出完全一致。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第6章代码包:enumerate(含1 个 Notebook)
    ZIP · 580B
    下载