Python zip() 函数详解

Python zip()函数详解


zip()是Python内置函数,用于将多个可迭代对象打包成元组组成的迭代器。


它接收任意数量的可迭代对象作为参数,返回一个元组迭代器,每个元组包含来自各可迭代对象的对应位置元素。


主要特点包括:默认以最短的可迭代对象为准,可通过itertools.zip_longest()处理不同长度的情况。


常见应用场景包括创建字典、并行遍历多个列表、矩阵转置等。


zip()具有高效的内存使用(惰性求值),但需要注意zip对象只能使用一次,且不同长度时会丢失数据。


与enumerate()相比,zip()更适合处理多个序列的并行操作。


掌握zip()可以编写更简洁高效的Python代码。


Python zip() 函数详解


zip() 是 Python 的内置函数,用于将多个可迭代对象打包成元组组成的迭代器


1. 基本语法

python

复制代码
zip(*iterables)

参数:

  • *iterables:一个或多个可迭代对象(列表、元组、字符串等)

返回值:

  • 返回一个元组迭代器,每个元组包含来自每个可迭代对象的对应位置元素

2. 基本用法

打包两个列表

python

复制代码
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]

result = zip(names, scores)
print(result)  # <zip object at 0x...>
print(list(result))  # [('Alice', 85), ('Bob', 92), ('Charlie', 78)]

打包三个列表

python

复制代码
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
scores = [85, 92, 78]

result = list(zip(names, ages, scores))
print(result)
# [('Alice', 25, 85), ('Bob', 30, 92), ('Charlie', 35, 78)]

打包字符串

python

复制代码
word1 = "abc"
word2 = "123"

result = list(zip(word1, word2))
print(result)  # [('a', '1'), ('b', '2'), ('c', '3')]

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

默认行为:以最短的为准

python

复制代码
names = ['Alice', 'Bob', 'Charlie', 'David']
scores = [85, 92]

result = list(zip(names, scores))
print(result)  # [('Alice', 85), ('Bob', 92)]  # Charlie和David被忽略

使用 itertools.zip_longest() 以最长的为准

python

复制代码
from itertools import zip_longest

names = ['Alice', 'Bob', 'Charlie', 'David']
scores = [85, 92]

result = list(zip_longest(names, scores))
print(result)  # [('Alice', 85), ('Bob', 92), ('Charlie', None), ('David', None)]

# 指定填充值
result = list(zip_longest(names, scores, fillvalue=0))
print(result)  # [('Alice', 85), ('Bob', 92), ('Charlie', 0), ('David', 0)]

4. 常见应用场景

场景1:创建字典

python

复制代码
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Beijing']

# 使用 zip 创建字典
dictionary = dict(zip(keys, values))
print(dictionary)  # {'name': 'Alice', 'age': 25, 'city': 'Beijing'}

场景2:并行遍历多个列表

python

复制代码
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
cities = ['Beijing', 'Shanghai', 'Guangzhou']

for name, age, city in zip(names, ages, cities):
    print(f'{name} is {age} years old and lives in {city}')
# 输出:
# Alice is 25 years old and lives in Beijing
# Bob is 30 years old and lives in Shanghai
# Charlie is 35 years old and lives in Guangzhou

场景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(row) for row in zip(*matrix)]
print(transposed)  # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

场景4:拆解列表(解压)

python

复制代码
# 压缩
pairs = [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
names, scores = zip(*pairs)

print(names)   # ('Alice', 'Bob', 'Charlie')
print(scores)  # (85, 92, 78)

场景5:同时遍历字典的键和值

python

复制代码
# 方法1:直接使用 items()
d = {'a': 1, 'b': 2, 'c': 3}
for key, value in d.items():
    print(f'{key}: {value}')

# 方法2:使用 zip(不推荐,但可行)
for key, value in zip(d.keys(), d.values()):
    print(f'{key}: {value}')

5. 实际应用示例

示例1:计算学生总分

python

复制代码
students = ['Alice', 'Bob', 'Charlie']
scores_math = [85, 92, 78]
scores_english = [88, 85, 90]
scores_python = [95, 88, 92]

for student, math, eng, py in zip(students, scores_math, scores_english, scores_python):
    total = math + eng + py
    print(f'{student}: 总分 {total}')
# 输出:
# Alice: 总分 268
# Bob: 总分 265
# Charlie: 总分 260

示例2:格式化输出表格

python

复制代码
headers = ['Name', 'Age', 'City']
data = [
    ['Alice', 25, 'Beijing'],
    ['Bob', 30, 'Shanghai'],
    ['Charlie', 35, 'Guangzhou']
]

# 打印表头
print(f"{headers[0]:<10} {headers[1]:<6} {headers[2]:<10}")
print("-" * 28)

# 打印数据
for row in data:
    print(f"{row[0]:<10} {row[1]:<6} {row[2]:<10}")

# 或使用 zip 转置
for row in zip(*data):
    print(f"{row[0]:<10} {row[1]:<6} {row[2]:<10}")

示例3:比较两个列表的差异

python

复制代码
list1 = [1, 2, 3, 4, 5]
list2 = [1, 2, 0, 4, 6]

for a, b in zip(list1, list2):
    if a != b:
        print(f'差异: {a} vs {b}')
# 输出:
# 差异: 3 vs 0
# 差异: 5 vs 6

示例4:添加索引

python

复制代码
names = ['Alice', 'Bob', 'Charlie']
# 使用 enumerate 更合适,但 zip 也可以
for i, name in zip(range(len(names)), names):
    print(f'{i}: {name}')

# 更好的方式
for i, name in enumerate(names):
    print(f'{i}: {name}')

示例5:处理多个列表的筛选

python

复制代码
names = ['Alice', 'Bob', 'Charlie', 'David']
ages = [25, 30, 35, 40]
scores = [85, 92, 78, 88]

# 找出成绩大于80的学生
filtered = [(name, age, score) for name, age, score in zip(names, ages, scores) if score > 80]
print(filtered)
# [('Alice', 25, 85), ('Bob', 30, 92), ('David', 40, 88)]

6. zip() 的高级用法

使用 * 解包操作符

python

复制代码
# 解包列表
data = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*data)
print(letters)  # ('a', 'b', 'c')
print(numbers)  # (1, 2, 3)

# 解包嵌套列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = list(zip(*matrix))

sorted() 结合使用

python

复制代码
names = ['Charlie', 'Alice', 'Bob']
scores = [78, 85, 92]

# 按分数排序
sorted_pairs = sorted(zip(scores, names))
print(sorted_pairs)  # [(78, 'Charlie'), (85, 'Alice'), (92, 'Bob')]

# 按分数排序后只取名字
sorted_names = [name for score, name in sorted(zip(scores, names))]
print(sorted_names)  # ['Charlie', 'Alice', 'Bob']

7. 性能对比

python

复制代码
import time

# 方法1:使用索引
list1 = list(range(10000))
list2 = list(range(10000))

start = time.time()
result = [(list1[i], list2[i]) for i in range(len(list1))]
print(f"索引方式: {time.time() - start:.5f}秒")

# 方法2:使用 zip
start = time.time()
result = list(zip(list1, list2))
print(f"zip方式: {time.time() - start:.5f}秒")
# zip 通常更快且更 Pythonic

8. 注意事项和常见陷阱

陷阱1:zip 只能使用一次

python

复制代码
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]

zipped = zip(names, scores)
print(list(zipped))  # [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
print(list(zipped))  # []  第二次为空!

陷阱2:不同长度时的数据丢失

python

复制代码
names = ['Alice', 'Bob', 'Charlie', 'David']
scores = [85, 92]

result = dict(zip(names, scores))
print(result)  # {'Alice': 85, 'Bob': 92}  # Charlie 和 David 丢失!

陷阱3:空可迭代对象

python

复制代码
result = list(zip([], [1, 2, 3]))
print(result)  # [] 空列表

9. 与其他函数对比

函数 功能 返回值 适用场景
zip() 并行打包 元组迭代器 多个序列并行处理
map() 应用函数 迭代器 对序列应用函数
enumerate() 添加索引 索引-值对 需要索引的遍历

python

复制代码
# zip vs enumerate
names = ['Alice', 'Bob', 'Charlie']

# zip 方式
for i, name in zip(range(len(names)), names):
    print(i, name)

# enumerate 方式(更优)
for i, name in enumerate(names):
    print(i, name)

10. 实用技巧汇总

python

复制代码
# 1. 创建字典
d = dict(zip(['a', 'b', 'c'], [1, 2, 3]))

# 2. 并行循环
for a, b in zip(list_a, list_b):
    pass

# 3. 矩阵转置
transposed = list(zip(*matrix))

# 4. 拆分成两个列表
list1, list2 = zip(*list_of_pairs)

# 5. 添加默认值(使用 zip_longest)
from itertools import zip_longest
pairs = list(zip_longest(list1, list2, fillvalue=0))

# 6. 生成相邻元素对
lst = [1, 2, 3, 4, 5]
pairs = list(zip(lst, lst[1:]))  # [(1,2), (2,3), (3,4), (4,5)]

# 7. 生成偏移对
offset = 2
offset_pairs = list(zip(lst, lst[offset:]))  # [(1,3), (2,4), (3,5)]

总结表

特性 说明
类型 内置函数
返回值 zip 对象(迭代器)
参数 多个可迭代对象
长度处理 以最短的为准
主要用途 并行打包、解包、字典创建
内存效率 高(惰性求值)
Pythonic ✅ 非常 Pythonic

最佳实践

  • ✅ 使用 zip() 进行并行遍历

  • ✅ 使用 dict(zip(keys, values)) 创建字典

  • ✅ 使用 zip(*matrix) 进行矩阵转置

  • ✅ 结合列表推导式进行筛选

  • ⚠️ 注意不同长度的可迭代对象

  • ⚠️ zip 对象只能使用一次

  • 💡 需要填充值时使用 itertools.zip_longest()


zip() 是 Python 中最实用的函数之一,掌握它可以编写更简洁、更高效的代码!

相关推荐
2401_887724502 小时前
SQL注入的安全架构设计_将数据库置于内网隔离区
jvm·数据库·python
m0_678485452 小时前
如何配置文件描述符限制_limits.conf中Oracle用户配置
jvm·数据库·python
2401_835956812 小时前
HTML5中Canvas局部刷新区域重绘的算法优化
jvm·数据库·python
Irene19912 小时前
大数据开发场景中,Python 常用且易错易混淆的知识点总结(附:从实战角度梳理的 Python 知识体系)
大数据·python
weixin_408717772 小时前
如何导入带系统变量修改的SQL_确保SUPER权限并规避只读变量报错
jvm·数据库·python
m0_678485452 小时前
c++怎么编写多线程安全的跨平台文件日志库_无锁队列与异步IO【附源码】
jvm·数据库·python
m0_746752302 小时前
PHP源码运行时风扇狂转怎么办_硬件温控调优方法【说明】
jvm·数据库·python
落羽的落羽2 小时前
【Linux系统】深入线程:多线程的互斥与同步原理,封装实现两种生产者消费者模型
java·linux·运维·服务器·c++·人工智能·python
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年4月17日
人工智能·python·信息可视化·自然语言处理·ai编程