python中的zip() 函数介绍及使用说明

发布于:2025-09-04 ⋅ 阅读:(25) ⋅ 点赞:(0)

zip() 是 Python 中非常实用的内置函数,用于将多个可迭代对象中对应的元素打包成元组,然后返回由这些元组组成的迭代器。

1. 基本语法和功能

语法

python

zip(iterable1, iterable2, ..., iterableN)

基本功能

python

# 将两个列表的对应元素配对
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]

zipped = zip(names, ages)
print(list(zipped))  # [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

# 可以处理多个可迭代对象
cities = ["New York", "London", "Tokyo"]
zipped = zip(names, ages, cities)
print(list(zipped))  # [('Alice', 25, 'New York'), ('Bob', 30, 'London'), ('Charlie', 35, 'Tokyo')]

2. 不同长度的可迭代对象处理

python

# 当可迭代对象长度不同时,以最短的为准
names = ["Alice", "Bob", "Charlie", "David"]
ages = [25, 30]  # 只有两个元素

zipped = zip(names, ages)
print(list(zipped))  # [('Alice', 25), ('Bob', 30)] - 只取前两个

# 使用 itertools.zip_longest() 可以以最长的为准
from itertools import zip_longest

zipped_long = zip_longest(names, ages, fillvalue="未知")
print(list(zipped_long))  # [('Alice', 25), ('Bob', 30), ('Charlie', '未知'), ('David', '未知')]

3. 常见使用场景

场景1:并行迭代多个列表

python

names = ["张三", "李四", "王五"]
scores = [85, 92, 78]
subjects = ["数学", "英语", "物理"]

for name, score, subject in zip(names, scores, subjects):
    print(f"{name}的{subject}成绩是:{score}分")
# 输出:
# 张三的数学成绩是:85分
# 李四的英语成绩是:92分
# 王五的物理成绩是:78分

场景2:创建字典

python

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'}

# 从两个列表创建字典
fruits = ["apple", "banana", "cherry"]
prices = [1.2, 0.8, 2.5]
fruit_prices = dict(zip(fruits, prices))
print(fruit_prices)  # {'apple': 1.2, 'banana': 0.8, 'cherry': 2.5}

场景3:矩阵转置

python

# 二维列表转置
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)]

# 转置后再转回列表形式
transposed_list = [list(row) for row in transposed]
print(transposed_list)  # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

场景4:数据分组处理

python

# 将数据分成多个组
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
group_size = 3

groups = list(zip(*[iter(data)] * group_size))
print(groups)  # [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

# 如果数据不能整除,可以使用 itertools.zip_longest
from itertools import zip_longest

data = [1, 2, 3, 4, 5, 6, 7]
groups = list(zip_longest(*[iter(data)] * 3, fillvalue=None))
print(groups)  # [(1, 2, 3), (4, 5, 6), (7, None, None)]

4. 与 * 操作符配合使用(解包)

python

# 解包已压缩的数据
zipped_data = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
names, ages = zip(*zipped_data)

print(names)   # ('Alice', 'Bob', 'Charlie')
print(ages)    # (25, 30, 35)

# 实际应用:分离数据
students = [
    ("张三", 85, "数学"),
    ("李四", 92, "英语"),
    ("王五", 78, "物理")
]

names, scores, subjects = zip(*students)
print(f"姓名: {names}")      # 姓名: ('张三', '李四', '王五')
print(f"成绩: {scores}")     # 成绩: (85, 92, 78)
print(f"科目: {subjects}")   # 科目: ('数学', '英语', '物理')

5. 在列表推导式中的应用

python

# 使用 zip() 进行复杂计算
list1 = [1, 2, 3, 4]
list2 = [10, 20, 30, 40]

# 对应元素相加
result = [x + y for x, y in zip(list1, list2)]
print(result)  # [11, 22, 33, 44]

# 对应元素相乘
result = [x * y for x, y in zip(list1, list2)]
print(result)  # [10, 40, 90, 160]

# 条件筛选
result = [x for x, y in zip(list1, list2) if y > 15]
print(result)  # [2, 3, 4] - 只取 list2 中大于15的对应元素

6. 处理文件数据

python

# 读取CSV文件并处理(示例)
# 假设有一个 students.csv 文件:
# name,age,score
# Alice,25,85
# Bob,30,92
# Charlie,35,78

# 模拟读取CSV文件
lines = [
    "name,age,score",
    "Alice,25,85",
    "Bob,30,92",
    "Charlie,35,78"
]

# 获取标题行
headers = lines[0].split(',')
print(headers)  # ['name', 'age', 'score']

# 处理数据行
data = []
for line in lines[1:]:
    values = line.split(',')
    data.append(values)

print(data)  # [['Alice', '25', '85'], ['Bob', '30', '92'], ['Charlie', '35', '78']]

# 使用 zip() 创建字典列表
students = []
for row in data:
    student = dict(zip(headers, row))
    students.append(student)

print(students)
# [{'name': 'Alice', 'age': '25', 'score': '85'},
#  {'name': 'Bob', 'age': '30', 'score': '92'},
#  {'name': 'Charlie', 'age': '35', 'score': '78'}]

7. 与 enumerate() 结合使用

python

names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]

# 同时获取索引和对应的元素
for i, (name, score) in enumerate(zip(names, scores)):
    print(f"第{i+1}个学生: {name}, 成绩: {score}")
# 输出:
# 第1个学生: Alice, 成绩: 85
# 第2个学生: Bob, 成绩: 92
# 第3个学生: Charlie, 成绩: 78

8. 性能考虑和注意事项

内存效率

python

# zip() 返回的是迭代器,节省内存
large_list1 = range(1000000)
large_list2 = range(1000000)

zipped = zip(large_list1, large_list2)  # 不会立即创建所有元组
print(zipped)  # <zip object at 0x...>

# 只有在需要时才计算
first_few = list(zipped)[:5]  # 只计算前5个
print(first_few)  # [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

注意事项

python

# 1. zip() 返回的是迭代器,只能遍历一次
zipped = zip([1, 2, 3], ['a', 'b', 'c'])
first_pass = list(zipped)  # [(1, 'a'), (2, 'b'), (3, 'c')]
second_pass = list(zipped)  # [] - 已经耗尽

# 2. 如果需要多次使用,可以转换为列表
zipped_list = list(zip([1, 2, 3], ['a', 'b', 'c']))
print(zipped_list)  # [(1, 'a'), (2, 'b'), (3, 'c')]
print(zipped_list)   # [(1, 'a'), (2, 'b'), (3, 'c')] - 可以多次使用

# 3. 空的可迭代对象
empty_zip = zip([], [])
print(list(empty_zip))  # []

# 4. 单个可迭代对象
single_zip = zip([1, 2, 3])
print(list(single_zip))  # [(1,), (2,), (3,)]

9. 实际项目中的应用示例

示例1:学生成绩处理

python

def calculate_grades(students, scores, weights):
    """计算加权平均分"""
    weighted_scores = []
    for student, score_list, weight_list in zip(students, scores, weights):
        total = sum(s * w for s, w in zip(score_list, weight_list))
        weighted_scores.append((student, total))
    return weighted_scores

# 使用示例
students = ["张三", "李四"]
scores = [[85, 90, 78], [92, 88, 95]]  # 各科成绩
weights = [[0.3, 0.4, 0.3], [0.3, 0.4, 0.3]]  # 各科权重

results = calculate_grades(students, scores, weights)
for student, score in results:
    print(f"{student}的加权平均分: {score:.2f}")
# 输出:
# 张三的加权平均分: 84.90
# 李四的加权平均分: 91.90

示例2:数据验证

python

def validate_data(required_fields, input_data):
    """验证输入数据是否包含所有必需字段"""
    missing_fields = []
    for field, value in zip(required_fields, input_data):
        if not value:
            missing_fields.append(field)
    return missing_fields

# 使用示例
required = ["username", "email", "password"]
user_input = ["john_doe", "", "secret123"]  # 邮箱为空

missing = validate_data(required, user_input)
if missing:
    print(f"缺少必填字段: {missing}")  # 缺少必填字段: ['email']
else:
    print("所有字段都已填写")

总结

zip() 函数是 Python 中非常强大的工具,主要用途包括:

  1. 并行迭代:同时遍历多个可迭代对象

  2. 数据配对:将相关数据组合在一起

  3. 字典创建:从两个列表快速创建字典

  4. 矩阵转置:处理二维数据

  5. 数据分组:将数据分成指定大小的组

优点

  • 内存高效(返回迭代器)

  • 代码简洁易读

  • 支持任意数量的可迭代对象

注意事项

  • 迭代器只能使用一次

  • 以最短的可迭代对象为准

  • 需要时可以使用 itertools.zip_longest()

掌握 zip() 函数可以让你写出更加 Pythonic 和高效的代码!


网站公告

今日签到

点亮在社区的每一天
去签到