zip()
函数将来自多个可迭代对象或者序列的数据交叉组合在一起,将带有 n 个元素的可迭代对象或者序列转换为 n 元组。前面的例子用zip()
函数将两个样本集的数据组合在一起,生成了一个二元组序列。
zip()
函数返回一个生成器,而不会将返回结果实例化。
zip()
函数的作用如下:
>>> xi = [1.47, 1.50, 1.52, 1.55, 1.57, 1.60, 1.63, 1.65,
... 1.68, 1.70, 1.73, 1.75, 1.78, 1.80, 1.83,]
>>> yi = [52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29,
... 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46,]
>>> zip(xi, yi)
<zip object at 0x101d62ab8>
>>> list(zip(xi, yi))
[(1.47, 52.21), (1.5, 53.12), (1.52, 54.48), (1.55, 55.84),
(1.57, 57.2), (1.6, 58.57), (1.63, 59.93), (1.65, 61.29),
(1.68, 63.11), (1.7, 64.47), (1.73, 66.28), (1.75, 68.1),
(1.78, 69.92), (1.8, 72.19), (1.83, 74.46)]
zip()
函数需要处理一些特殊情况,比如我们需要知道下列情形中它的运行方式。
- 如果没有输入参数会怎样?
-
如果只有一个输入参数会怎样?
-
如果作为输入参数的序列长度不一致会怎样?
对于其他函数(例如any()
、all()
、len()
和sum()
等),我们需要知道归约空序列时的单位元是什么。例如sum(())
返回0,借助这个概念可以求得zip()
函数的单位元。
显然,每种特殊情况都会生成某种可迭代对象,下面的代码演示了这些情况下zip()
函数的行为。空输入参数的情况如下:
>>> zip()
<zip object at 0x101d62ab8>
>>> list(_)
[]
可见没有输入参数的zip()
函数返回一个生成器函数,但里面不含任何数据项,这符合输出为可迭代对象的要求。
单个输入参数的情况如下:
>>> zip((1,2,3))
<zip object at 0x101d62ab8>
>>> list(_)
[(1,), (2,), (3,)]
这种情况下,zip()
函数返回单元组序列,也是符合要求的。
输入序列的长度不同时zip()
函数的行为如下:
>>> list(zip((1, 2, 3), ('a', 'b')))
[(1, 'a'), (2, 'b')]
对于这个结果,Python社区内部存在争议,为什么要截断?为什么不用None
值填充较短的列表?作为zip()
函数的替代,itertools
模块的zip_longest()
函数满足上面的要求。