range 函数详解
基本功能
range() 用于生成一个不可变的整数序列,常用于 for 循环中控制迭代次数。
它不直接返回列表,而是返回一个 range 对象(可迭代、惰性计算)。
语法
1 2 3
   | range(stop) range(start, stop) range(start, stop, step)
   | 
 
| 参数 | 
含义 | 
| start | 
起始值(包含),默认为 0 | 
| stop | 
结束值(不包含) | 
| step | 
步长,默认为 1 | 
使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   |  for i in range(5):     print(i)  
 
  for i in range(2, 6):     print(i)  
 
  for i in range(0, 10, 2):     print(i)  
 
  for i in range(5, 0, -1):     print(i)  
 
  | 
 
range 对象的特性
- 内存高效:不是一次性生成所有数字,而是“惰性计算”,只在需要时生成下一个值。
 
- 可迭代但不可变:不能修改元素,也不能赋值。
 
- 支持索引和切片(Python 3.2+):
 
1 2 3
   | r = range(2, 10, 2) print(r[1])       print(r[:2])     
   | 
 
1
   | 1000 in range(0, 10000, 2)  
   | 
 
转换为列表或元组
如果需要立即得到所有值:
1 2
   | list(range(5))         tuple(range(2, 8))    
   | 
 
注意:range 本身不是列表,使用 list() 才会真正生成数据。
常见用途
| 场景 | 
示例 | 
| 控制循环次数 | 
for i in range(10): | 
| 遍历索引 | 
for i in range(len(lst)): | 
| 生成等差数列 | 
range(0, 100, 5) | 
| 反向遍历 | 
range(len(lst)-1, -1, -1) | 
常见误区
错误:认为 range 返回列表(实际是对象)
正确:range(5) 是 <class 'range'> 类型
 
错误:试图修改 range 元素
range 是不可变的
 
错误:用 range(len(...)) 遍历元素(应优先用 for item in lst)
推荐:只有需要索引时才用 range(len(lst)),否则用直接遍历
 
enumerate 函数详解
基本功能
enumerate() 用于在遍历可迭代对象时,同时获取索引和元素值,避免手动维护计数器。
语法
1
   | enumerate(iterable, start=0)
   | 
 
| 参数 | 
含义 | 
| iterable | 
任意可迭代对象(列表、字符串、元组等) | 
| start | 
起始索引,默认为 0 | 
使用示例
1 2 3 4 5 6 7 8
   | lst = ['a', 'b', 'c']
  for i, value in enumerate(lst):     print(i, value)
 
 
 
 
   | 
 
自定义起始索引
1 2 3 4 5 6
   | for i, value in enumerate(lst, start=1):     print(i, value)
 
 
 
 
   | 
 
遍历字符串
1 2 3 4 5
   | for i, ch in enumerate("hello"):     print(i, ch)
 
 
 
  | 
 
enumerate 返回什么
enumerate() 返回一个枚举对象(iterator),每次迭代返回一个 (index, value) 元组。
你可以将其转为列表查看内容:
1
   | list(enumerate(['x', 'y']))  
   | 
 
底层原理
enumerate 等价于以下生成器函数:
1 2 3 4 5
   | def my_enumerate(iterable, start=0):     count = start     for item in iterable:         yield count, item         count += 1
   | 
 
所以它是惰性计算的,内存友好。
实际应用场景
场景 1:需要索引和值
1 2
   | for idx, name in enumerate(names):     print(f"{idx+1}. {name}")
   | 
 
场景 2:查找满足条件的索引
1 2 3 4
   | for i, x in enumerate(nums):     if x == target:         print(f"Found at index {i}")         break
   | 
 
场景 3:与 zip 结合处理多个列表
1 2
   | for i, (a, b) in enumerate(zip(list1, list2)):     print(f"{i}: {a} vs {b}")
   | 
 
常见误区
错误:认为 enumerate 是从 1 开始的
默认从 0 开始,可用 start= 修改
 
错误:只用于列表
可用于任何可迭代对象:字符串、元组、字典键、生成器等
 
错误:在循环中修改 i 能跳过元素
i 是局部变量,修改不影响循环流程
 
对比:range 与 enumerate
| 特性 | 
range(len(lst)) | 
enumerate(lst) | 
| 是否需要索引 | 
是 | 
是 | 
| 是否需要元素值 | 
需要 lst[i] | 
直接获取 | 
| 代码可读性 | 
一般 | 
更好 | 
| 性能 | 
略快(纯整数) | 
稍慢(生成元组) | 
| 内存 | 
惰性 | 
惰性 | 
| 推荐程度 | 
不推荐用于遍历元素 | 
强烈推荐 | 
推荐写法对比
1 2 3 4 5 6 7
   |  for i in range(len(lst)):     print(i, lst[i])
 
  for i, value in enumerate(lst):     print(i, value)
 
  | 
 
高级技巧与组合用法
enumerate 与 range 组合使用
如果你想从某个索引开始遍历一段序列:
1 2 3 4 5 6 7 8 9 10
   | lst = ['a', 'b', 'c', 'd', 'e'] start_idx = 2 end_idx = 5
  for i, value in enumerate(lst[start_idx:end_idx], start=start_idx):     print(i, value)
 
 
 
 
   | 
 
这样索引是原始位置,不是切片后的 0,1,2。
enumerate 配合条件跳过
1 2 3 4
   | for i, char in enumerate(s):     if char == ' ':         continue       print(i, char)
   | 
 
获取 enumerate 的长度
enumerate 是迭代器,不支持 len():
1 2 3 4 5
   | e = enumerate([1,2,3])
 
 
  len(list(enumerate([1,2,3])))  
   | 
 
1 2 3 4 5
   | from itertools import islice
 
  for i, x in islice(enumerate(large_iterable), 5):     print(i, x)
   | 
 
性能对比(小数据无差别)
| 方法 | 
适用场景 | 
性能 | 
| for x in lst | 
只需要值 | 
最快 | 
| for i, x in enumerate(lst) | 
需要索引+值 | 
推荐 | 
| for i in range(len(lst)) | 
需要索引+值 | 
可用但不优雅 | 
| for i in range(n) | 
固定次数循环 | 
必用 | 
对于小数据,性能差异可忽略;对于大循环,enumerate 更安全、可读性更高。
总结:最佳实践
| 问题 | 
推荐做法 | 
| 遍历列表并需要索引 | 
for i, x in enumerate(lst) | 
| 只需要元素 | 
for x in lst | 
| 固定次数循环 | 
for i in range(n) | 
| 反向遍历索引 | 
for i in range(len(lst)-1, -1, -1) | 
| 从某索引开始枚举 | 
enumerate(lst[start:], start=start) | 
| 提取带索引的数据 | 
list(enumerate(…)) | 
一句话口诀记忆
range 造数字,enumerate 配对出(索引, 元素)