在Python开发中,经常需要把多个列表按索引一一对应地处理,比如学生姓名、年龄、邮箱分别存储在不同列表,然后输出每个人的完整信息。传统的range(len())写法虽然可行,但不够Pythonic。zip()函数能够将多个可迭代对象的对应元素打包成元组,从而实现优雅的并行遍历。本文从基础用法到高级技巧,配合实战案例,帮你彻底掌握zip()。
- names = ["张三", "李四", "王五"]
- ages = [25, 30, 28]
- emails = ["zs@test.com", "ls@test.com", "ww@test.com"]
- # 传统写法(不推荐)
- for i in range(len(names)):
- print(f"{names[i]}, {ages[i]}岁, {emails[i]}")
- # 使用zip(推荐)
- for name, age, email in zip(names, ages, emails):
- print(f"{name}, {age}岁, {email}")
复制代码
一、zip()的基本用法
zip(*iterables)将多个可迭代对象的对应元素打包成元组,返回一个迭代器。如果传入的序列长度不一致,zip默认按最短的截断,多余元素被丢弃。如果希望按最长处理并填充缺失值,可以使用itertools.zip_longest,并指定fillvalue参数。- from itertools import zip_longest
- short = [1, 2]
- long_list = [1, 2, 3, 4, 5]
- print(list(zip(short, long_list))) # [(1, 1), (2, 2)] 截断
- print(list(zip_longest(short, long_list, fillvalue=0))) # [(1,1),(2,2),(0,3),(0,4),(0,5)]
复制代码 如果需要严格检查长度一致性,Python 3.10+提供了strict参数:zip(a, b, strict=True)会在长度不匹配时抛出ValueError。也可以手动实现一个strict_zip函数来兼容旧版本。
zip对象是迭代器,只能遍历一次。需要多次使用时应先转换为列表。
二、经典应用
1. 并行遍历:同时处理多列数据,如学生各科成绩和姓名。- students = ["张三", "李四", "王五"]
- math = [85, 92, 78]
- eng = [88, 86, 95]
- for name, m, e in zip(students, math, eng):
- print(f"{name}: 数学{m}, 英语{e}")
复制代码 2. 构建字典:dict(zip(keys, values))快速从两个列表创建映射。- keys = ["name", "age", "city"]
- values = ["张三", 25, "北京"]
- user = dict(zip(keys, values))
复制代码 3. 转置矩阵:zip(*matrix)将行转换为列。- matrix = [[1,2,3],[4,5,6],[7,8,9]]
- transposed = list(zip(*matrix))
- print(transposed) # [(1,4,7),(2,5,8),(3,6,9)]
复制代码 4. 成对处理:zip(data, data[1:])可以生成相邻元素对,用于计算移动平均或比较相邻变化。
三、zip与*解包的组合
zip(*pairs)可以把已经打包的元组列表“解压缩”回原始序列,称为unzip。例如将用户元组列表分离成姓名、年龄、城市三个元组。- users = [("张三",25,"北京"),("李四",30,"上海")]
- names, ages, cities = zip(*users)
- print(names, ages, cities)
复制代码 行式数据与列式数据之间互相转换也很方便。
四、高级用法
1. 创建滑动窗口:zip(*(iterable[i:] for i in range(n)))可以实现大小为n的滑动窗口。
2. 多键排序:可以将排序键和原数据一起zip,然后排序后解包(装饰-排序-去装饰模式)。更常见的做法是直接用sorted的key参数。
3. 同时遍历多个字典:先确保键顺序一致,再用zip(dict1.values(), dict2.values())进行并行处理。
五、实战案例
1. 成绩合并计算器:ScoreMerger类接收姓名列表和各科成绩列表,利用zip构建成绩矩阵,计算总分、科目平均分和排名,并格式化输出报告。代码见原文章节6.1。
2. 配置文件对比工具:compare_configs函数接收两个配置字典,用zip遍历所有键,对比值的变化,输出新增、删除、修改的项。代码见原文章节6.2。
六、总结
zip()是Python中处理并行迭代的利器,核心要点:默认截断最短序列,返回迭代器,结合*解包可以实现行列转换,itertools.zip_longest处理不等长序列,Python 3.10+支持strict模式。遇到需要手写range(len())的场景,优先考虑zip()。 |