下面用通俗+例子来说明 enumerate 和 zip 在 Python 里的作用、常见用法与易错点。
一、enumerate(iterable, start=0)
作用:在遍历可迭代对象时,同时得到“索引(下标)+ 元素”。返回值:一个迭代器(惰性产生 (index, item) 元组)。
语法
enumerate(iterable, start=0)
iterable:可迭代对象(如 list、tuple、str、generator 等)start:索引起始值(默认为 0,可改为 1 等)
常用示例
1) 基本遍历(带索引)
fruits = ["apple", "banana", "cherry"]for i, name in enumerate(fruits): print(i, name)# 输出:# 0 apple# 1 banana# 2 cherry
2) 从 1 开始计数(常用于展示行号)
for i, line in enumerate(open("data.txt", encoding="utf-8"), start=1): print(f"{i}: {line.strip()}")
3) 在遍历时“原地修改”列表(需要索引)
nums = [10, 20, 30]for i, v in enumerate(nums): nums[i] = v * 2# nums -> [20, 40, 60]
4) 搭配 zip 同时拿到“对齐后的索引与元素”
a = ["A", "B", "C"]b = [1, 2, 3]for idx, (x, y) in enumerate(zip(a, b), start=1): print(idx, x, y)
小结
- 对比
for i in range(len(lst)):enumerate 更Pythonic、可读性更好,也避免多次索引。 - 它是惰性的,不会一次性把全部结果展开,有利于内存。
二、zip(*iterables)
作用:把多个可迭代对象按位置对齐“拉链式”组合成元组序列。返回值:一个迭代器(惰性产生 (a[i], b[i], ...) 的元组)。长度:以最短的输入序列为准(超出的元素会被丢弃)。
语法
zip(iter1, iter2, ..., iterN)
常用示例
1) 并行遍历多个列表
names = ["Alice", "Bob", "Cathy"]scores = [90, 85, 92]for name, score in zip(names, scores): print(name, score)
2) 由两个列表构造字典
keys = ["id", "name", "age"]vals = [1001, "Alice", 23]d = dict(zip(keys, vals))# d -> {'id': 1001, 'name': 'Alice', 'age': 23}
3) 转置二维列表(行列互换)
matrix = [ [1, 2, 3], [4, 5, 6],]transposed = list(zip(*matrix))# transposed -> [(1, 4), (2, 5), (3, 6)]
4) 搭配 enumerate,在并行遍历时保留序号
a = ["x", "y", "z"]b = [10, 20, 30]for i, (x, y) in enumerate(zip(a, b), start=1): print(f"{i}. {x} -> {y}")
注意点 & 进阶
- 不同长度会截断:
list(zip([1,2,3], ["a","b"])) # -> [(1,'a'), (2,'b')]
如需对齐到最长,请用 itertools.zip_longest:from itertools import zip_longestlist(zip_longest([1,2,3], ["a","b"], fillvalue=None))# -> [(1,'a'), (2,'b'), (3,None)]
zip 是惰性迭代器:需要一次性查看结果时,用 list(zip(...)) 转为列表。
何时用谁?
- 既要索引又要并行 →
enumerate(zip(a, b, ...), start=1)。 - 构造字典/配对数据 →
dict(zip(keys, values))。
小练习(加深记忆)
- 把两个列表
cols = ["name","age"] 与 vals = ["Alice", 23] 组为字典。 - 用
enumerate 打印列表 items = ["todo1","todo2"],序号从 1 开始。 - 将
[[1,2,3],[4,5,6],[7,8,9]] 行列互换。