Python中zip()函数详解:合并、解压与高效数据处理
在Python中,zip() 是一个非常实用的内置函数,用于将多个可迭代对象(如列表、元组、字符串等)合并成一个元组的列表。它通过将输入的每个可迭代对象的元素按位置配对,生成一个迭代器,其中每个元素是一个包含多个元素的元组。
基本语法
zip(*iterables)
- 参数:iterables 是一个或多个可迭代对象。
- 返回值:返回一个迭代器,其中每个元素是一个元组,包含来自每个可迭代对象的对应位置的元素。
基础用法
1. 合并两个列表
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
zipped = zip(list1, list2)
print(zipped) # 输出:
# 转换为列表查看结果
print(list(zipped)) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
2. 合并多个列表
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Tokyo"]
zipped = zip(names, ages, cities)
print(list(zipped))
# 输出: [('Alice', 25, 'New York'), ('Bob', 30, 'London'), ('Charlie', 35, 'Tokyo')]
处理不同长度的可迭代对象
如果输入的可迭代对象长度不一致,zip() 默认会以最短的可迭代对象的长度为准,忽略其他对象超出的部分。
list_a = [1, 2, 3, 4]
list_b = ['a', 'b']
zipped = zip(list_a, list_b)
print(list(zipped)) # 输出: [(1, 'a'), (2, 'b')]
解决方法:
如果需要保留所有元素(用默认值填充较短的列表),可以使用 itertools.zip_longest:
from itertools import zip_longest
zipped = zip_longest(list_a, list_b, fillvalue='---')
print(list(zipped))
# 输出: [(1, 'a'), (2, 'b'), (3, '---'), (4, '---')]
常见应用场景
1.创建字典
将两个列表合并为键值对的字典:
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'New York']
my_dict = dict(zip(keys, values))
print(my_dict) # 输出: {'name': 'Alice', 'age': 25, 'city': 'New York'}
2.同时遍历多个列表
fruits = ['apple', 'banana', 'cherry']
counts = [5, 3, 7]
for fruit, count in zip(fruits, counts):
print(f"{fruit}: {count}")
# 输出:
# apple: 5
# banana: 3
# cherry: 7
3.解压(Unzip)
通过 zip(*...) 可以将合并后的元组“解压”回原始列表:
zipped = [(1, 'a'), (2, 'b'), (3, 'c')]
unzipped = zip(*zipped)
print(list(unzipped)) # 输出: [(1, 2, 3), ('a', 'b', 'c')]
注意事项
- 迭代器特性:
zip() 返回的是一个迭代器,只能遍历一次。若需多次使用,需转换为列表:
zipped = zip([1,2], ['a','b'])
print(list(zipped)) # 第一次遍历
print(list(zipped)) # 第二次遍历(结果为空,因为迭代器已耗尽)
- 单个可迭代对象的处理:
如果只传入一个可迭代对象,zip() 会返回每个元素作为单元素元组:
zipped = zip([1, 2, 3])
print(list(zipped)) # 输出: [(1,), (2,), (3,)]
- Python 2 vs Python 3:
- Python 2 中 zip() 直接返回列表(如 [(1, 'a'), ...])。
- Python 3 中 zip() 返回迭代器,需用 list(zip(...)) 显式转换为列表。
高级技巧
1.与 map() 结合使用
numbers = [1, 2, 3]
squared = list(map(lambda x: x**2, numbers))
print(squared) # 输出: [1, 4, 9]
2.处理二维数据
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)]
总结
- 用途:合并多个可迭代对象为元组的集合。
- 特点:按位置配对,以最短长度为准。
- 应用场景:创建字典、同时遍历多个列表、数据对齐等。
- 扩展:结合 itertools.zip_longest 处理不等长数据,或用 zip(*...) 解压数据。
通过灵活使用 zip(),可以高效处理涉及多数据源同步操作的场景。