python每天一个技巧——Day 4 | 使用 zip 并行迭代
我们学习 Day 4:使用 zip 并行迭代。这是处理多个序列同步操作的强劲工具
深度解析:zip()函数
1. 基础用法:同步迭代多个序列
zip() 用于将多个可迭代对象”压缩”在一起,并行迭代
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
grades = ['A', 'A', 'B']
# 传统方法(不推荐)
for i in range(len(names)):
print(f"{names[i]}: {scores[i]}分, 等级: {grades[i]}")
print("---")
# 使用 zip()(推荐)
for name, score, grade in zip(names, scores, grades):
print(f"{name}: {score}分, 等级: {grade}")
输出:
Alice: 85分, 等级: A
Bob: 92分, 等级: A
Charlie: 78分, 等级: B
2.zip()的工作原理
zip() 创建一个迭代器,生成元组,其中每个元组包含来自各个可迭代对象的对应元素:
numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
zipped = zip(numbers, letters)
print(list(zipped)) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
3. 处理不同长度的序列
默认情况下,zip() 以最短的序列为准:
numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
zipped = zip(numbers, letters)
print(list(zipped)) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
3. 处理不同长度的序列
默认情况下,zip() 以最短的序列为准:
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c']
result = list(zip(list1, list2))
print(result) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
4.zip_longest():处理不同长度的序列
从 itertools 模块导入,以最长的序列为准,用指定值填充空缺:
from itertools import zip_longest
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c']
# 默认用 None 填充
result = list(zip_longest(list1, list2))
print(result) # 输出: [(1, 'a'), (2, 'b'), (3, 'c'), (4, None), (5, None)]
# 自定义填充值
result_custom = list(zip_longest(list1, list2, fillvalue='N/A'))
print(result_custom) # 输出: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'N/A'), (5, 'N/A')]
5. 实际应用场景
场景1:数据配对和处理
# 学生姓名和成绩配对
students = ['Alice', 'Bob', 'Charlie']
exam_scores = [85, 92, 78]
homework_scores = [90, 88, 85]
print("学生总成绩:")
for student, exam, hw in zip(students, exam_scores, homework_scores):
total = exam + hw
print(f"{student}: 考试{exam} + 作业{hw} = 总分{total}")
场景2:字典键值对操作
# 合并两个列表为字典
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'New York']
person_dict = dict(zip(keys, values))
print(person_dict) # 输出: {'name': 'Alice', 'age': 25, 'city': 'New York'}
# 字典键值交换
original = {'a': 1, 'b': 2, 'c': 3}
swapped = dict(zip(original.values(), original.keys()))
print(swapped) # 输出: {1: 'a', 2: 'b', 3: 'c'}
场景3:矩阵转置
# 使用 zip() 转置矩阵
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
transposed = list(zip(*matrix))
print("转置前:")
for row in matrix:
print(row)
print("转置后:")
for row in transposed:
print(row)
6. 高级用法技巧
技巧1:与 enumerate() 结合
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
for idx, (name, score) in enumerate(zip(names, scores), start=1):
print(f"{idx}. {name}: {score}分")
技巧2:解压序列
# 使用 * 操作符解压
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers, letters = zip(*pairs)
print(numbers) # 输出: (1, 2, 3)
print(letters) # 输出: ('a', 'b', 'c')
技巧3:并行排序
# 根据一个列表排序另一个列表
names = ['Charlie', 'Alice', 'Bob']
scores = [78, 85, 92]
# 先配对,再按分数排序
paired = sorted(zip(scores, names))
sorted_scores, sorted_names = zip(*paired)
print("按分数排序:")
for score, name in zip(sorted_scores, sorted_names):
print(f"{name}: {score}分")
7.zip_longest()的实用场景
from itertools import zip_longest
# 处理不完整的数据
students = ['Alice', 'Bob', 'Charlie', 'David']
midterm_scores = [85, 92] # 只有前两个学生的成绩
final_scores = [78, 88, 90] # 只有前三个学生的成绩
print("成绩表(缺考标记为0):")
for student, mid, final in zip_longest(students, midterm_scores, final_scores, fillvalue=0):
print(f"{student}: 期中{mid}, 期末{final}")
8. 实际项目案例
案例1:CSV 数据处理
def process_csv_data(headers, rows):
"""处理CSV格式数据"""
processed_data = []
for row in rows:
# 将每行数据与表头配对
row_dict = dict(zip(headers, row))
processed_data.append(row_dict)
return processed_data
# 模拟CSV数据
csv_headers = ['Name', 'Age', 'City']
csv_rows = [
['Alice', '25', 'New York'],
['Bob', '30', 'London'],
['Charlie', '22', 'Paris']
]
result = process_csv_data(csv_headers, csv_rows)
for item in result:
print(item)
案例2:配置管理系统
def merge_configs(default_config, user_config):
"""合并默认配置和用户配置"""
merged = {}
# 确保处理所有可能的键
all_keys = set(default_config.keys()) | set(user_config.keys())
for key in all_keys:
default_val = default_config.get(key)
user_val = user_config.get(key)
# 用户配置优先于默认配置
merged[key] = user_val if user_val is not None else default_val
return merged
# 使用示例
defaults = {'theme': 'dark', 'language': 'en', 'notifications': True}
user_prefs = {'language': 'zh', 'font_size': 14}
final_config = merge_configs(defaults, user_prefs)
print(final_config)
今日练习
练习1:基础应用
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
cities = ['New York', 'London', 'Paris']
# 使用 zip() 打印每个人的完整信息
# 你的代码 here
练习2:数据处理
prices = [100, 200, 150, 300]
quantities = [2, 1, 3]
# 计算每个商品的总价,处理不同长度的情况
# 使用 zip_longest,缺货商品总价为0
from itertools import zip_longest
# 你的代码 here
练习3:实战应用
def create_report(products, prices, sales):
"""
生成销售报告,包含产品、单价、销量、总销售额
处理不同长度的情况,缺失数据用0填充
"""
# 你的代码 here
pass
# 测试
products = ['A', 'B', 'C', 'D']
prices = [10, 20, 15]
sales = [100, 50, 80, 120, 30]
print(create_report(products, prices, sales))
练习答案:
# 练习1答案:
for name, age, city in zip(names, ages, cities):
print(f"{name}, {age}岁, 来自{city}")
# 练习2答案:
from itertools import zip_longest
total_prices = []
for price, qty in zip_longest(prices, quantities, fillvalue=0):
total = price * qty
total_prices.append(total)
print(total_prices) # 输出: [200, 200, 450, 0]
# 练习3答案:
from itertools import zip_longest
def create_report(products, prices, sales):
report = []
for product, price, sale in zip_longest(products, prices, sales, fillvalue=0):
revenue = price * sale
report.append(f"{product}: 单价{price}, 销量{sale}, 销售额{revenue}")
return "
".join(report)
今日总结
- zip(): 并行迭代多个序列,以最短序列为准
- zip_longest(): 以最长序列为准,可自定义填充值
- 适用场景: 数据配对、字典操作、矩阵转置等
- 最佳实践: 与 enumerate()、列表推导式等结合使用
记住:当你需要同步处理多个序列时,zip() 是你的首选工具!
明天我们将学习 Python 中超级优雅的特性:列表/字典/集合推导式。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...




