在遍历的过程当中,我们应当把序号以及内容都一并获取到。很多初学者在进行列表遍历操作的时候, 最容易犯的一个错误就是, 他们往往会选择手动去维护一个计数器的变量, 目的是为了搞清楚当前正在处理的是第几个元素。# 初级写法——手动计数fruits [苹果, 香蕉, 橘子, 葡萄]i 0for fruit in fruits:print(f第{i 1}个水果是{fruit})i 1# 高手写法——用 enumerate()for i, fruit in enumerate(fruits):print(f第{i 1}个水果是{fruit})当使用枚举的方式时, 系统会同时为你自动分配“序号”以及对应的实际数值。这种做法最大的好处在于, 你再也不用通过手动添加数字来维护一个计数器了。一、关于通过调用一个叫做 range 的函数来生成一连串数字的做法, 其中包含了有关这个函数的具体使用方法, 而在这里所讨论的是这种函数一共存在的三种具体的操作步骤。# range(stop) — 0 到 stop-1for i in range(5):print(i) # 0, 1, 2, 3, 4# range(start, stop) — start 到 stop-1for i in range(2, 7):print(i) # 2, 3, 4, 5, 6# range(start, stop, step) — 步长为 stepfor i in range(0, 20, 3):print(i) # 0, 3, 6, 9, 12, 15, 18# 步长为负数——倒序for i in range(10, 0, -2):print(i) # 10, 8, 6, 4, 21.2 range 不是列表r range(5)print(r) # range(0, 5) —— 不是一个完整的列表print(list(r)) # [0, 1, 2, 3, 4] —— 转成列表才能看到全部# range 的优点省内存# range(1000000) 只占几十个字节# list(range(1000000)) 占几 MB 内存# 判断元素是否在 range 里print(3 in range(5)) # Trueprint(100 in range(5)) # FalseO(1) 速度1.在具体的实际应用场景之中, 我们对于三个范围这样的概念进行了深入的探索与运用分析。# 1. 遍历列表的索引fruits [苹果, 香蕉, 橘子]for i in range(len(fruits)):print(f下标{i}{fruits[i]})# 2. 同时遍历两个列表names [张三, 李四, 王五]scores [85, 92, 78]for i in range(len(names)):print(f{names[i]}{scores[i]}分)# 3. 倒序遍历for i in range(len(fruits) - 1, -1, -1):print(fruits[i]) # 橘子、香蕉、苹果# 4. 每隔一个取一个for i in range(0, 10, 2):print(i) # 0, 2, 4, 6, 8# 5. 生成列表squares [x ** 2 for x in range(1, 11)]print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]二、同时拿出键和值。2.1 基本用法。fruits [苹果, 香蕉, 橘子, 葡萄]# 默认从 0 开始for i, fruit in enumerate(fruits):print(f下标{i}{fruit})# 指定起始编号for i, fruit in enumerate(fruits, start1):print(f第{i}个水果{fruit})# enumerate 返回的是什么enum enumerate(fruits)print(enum) #print(list(enum)) # [(0, 苹果), (1, 香蕉), (2, 橘子), (3, 葡萄)]2.2 的常见写法# 最常用for i, item in enumerate(列表):print(f{i}: {item})# 从1开始编号for i, item in enumerate(列表, 1):print(f第{i}个: {item})# 解包两个列表names [张三, 李四, 王五, 赵六]scores [85, 92, 78, 95]for i, (name, score) in enumerate(zip(names, scores), 1):print(f{i}. {name}{score}分)三、这是一个关于给列表中的每一个元素进行编号操作的实战案例, 具体为第一个实战环节。def show_todo_list(todos):显示带编号的待办事项if not todos:print( 暂无待办事项)returnprint(\n 待办事项)for i, todo in enumerate(todos, 1):print(f {i}. {todo})todos [买牛奶, 写作业, 健身, 看书]show_todo_list(todos)在进行实战2这个任务的时候, 你要做的是去查找那个元素的索引。def find_all_index(lst, target):查找列表中所有匹配项的索引indices [i for i, item in enumerate(lst) if item target]return indicesnumbers [1, 3, 5, 3, 7, 3, 9]print(find_all_index(numbers, 3)) # [1, 3, 5]print(find_all_index(numbers, 10)) # []进行实战训练之三, 其核心内容是为相关的数据打上对应的标签。def label_data(items):根据条件给数据打标签result []for i, item in enumerate(items):label A if item 80 else B if item 60 else Cresult.append((i, item, label))return resultscores [85, 42, 73, 90, 55, 68]labeled label_data(scores)for i, score, label in labeled:print(f 第{i1}项{score}分 → {label})进行实战环节中的第四个部分任务, 也就是生成数据报告。def generate_report(products):生成商品清单报告print( * 45)print(f{序号:4} {商品名:12} {价格:8} {库存:6})print(- * 45)total 0for i, (name, price, stock) in enumerate(products, 1):print(f{i:4d} {name:12s} ¥{price:6.2f} {stock:5d}件)total price * stockprint( * 45)print(f{库存总值¥:28s}{total:.2f})products [(手机, 2999, 50),(笔记本, 5999, 30),(耳机, 299, 200),(充电器, 99, 500),]generate_report(products)四、zip()——同时遍历多个列表另外, 和它关系比较近的zip这个操作方式, 在日常生活中也是经常被使用到的。names [张三, 李四, 王五]ages [25, 30, 28]scores [85, 92, 78]# 同时遍历三个列表for name, age, score in zip(names, ages, scores):print(f{name}{age}岁{score}分)# zip enumerate 强强联合for i, (name, age) in enumerate(zip(names, ages), 1):print(f{i}. {name}{age}岁)五、range 和 的内存对比import sys# range 非常省内存r range(1000000)print(frange 对象大小{sys.getsizeof(r)} 字节) # 48 字节# list(range()) 很费内存lst list(range(1000000))print(f列表大小{sys.getsizeof(lst)} 字节) # 8,000,056 字节# enumerate 也很省fruits [苹果, 香蕉, 橘子] * 10000e enumerate(fruits)print(fenumerate 对象大小{sys.getsizeof(e)} 字节) # 56 字节六、总结range()——生成数字序列range(5) → 0, 1, 2, 3, 4range(2, 7) → 2, 3, 4, 5, 6range(1, 10, 2)→ 1, 3, 5, 7, 9range(5, 0, -1)→ 5, 4, 3, 2, 1enumerate()——同时拿索引和值for i, item in enumerate(lst): → i从0开始for i, item in enumerate(lst, 1): → i从1开始zip()——同时遍历多个列表for a, b in zip(list1, list2): → 配对遍历选型口诀只要下标用 range(len(lst))只要元素用 for item in lst下标元素都用 enumerate(lst)同时遍历多个用 zip(lst1, lst2)全部都要用 enumerate(zip(lst1, lst2))课后练习有一组名单还有一连串的成绩数据, 用打印输出的功能来生成一个带有编号的表格内容, 利用特定的数值范围设置从十开始倒数到一的序列过程, 借助组合匹配函数把两组信息对接起来。字符串a, 字符串b, 字符串c把这两个东西放在一起, 然后弄成一个字典, 这个字典的形式是 {a: 1b: 2c: 3}。