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 中最实用的函数之一,掌握它可以编写更简洁、更高效的代码!

相关推荐
老白干19 小时前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙1 天前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能1 天前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂1 天前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study1 天前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境1 天前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境1 天前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1231 天前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102161 天前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb001 天前
一个项目带你入门AI应用开发01
python