假设需要将下列一维列表数据转换为数据对:
flat= ['2', '3', '5', '7', '11', '13', '17', '19', '23', '29',
'31', '37', '41', '43', '47', '53', '59', '61', '67', '71',... ]
可以运用列表切片技术:
zip(flat[0::2], flat[1::2])
切片flat[0::2]
表示列表中下标为偶数的所有元素,flat[1::2]
代表列表中下标为奇数的所有元素。将它们组合成二元组,其中第一个元素来自偶数下标列表,第二个元素来自奇数下标列表。当源列表长度是偶数时,这个方法效果很好。如果长度是奇数,忽略最后一个元素,稍后会给出解决方法。
这个实现的一个优点是简洁。对于相同的问题,前面的实现用的代码更多。
还可以进一步抽象,使用星号参数语法,创建指定长度的复合列表,如下所示:
zip(*(flat[i::n] for i in range(n)))
函数的返回结果是n
个切片:flat[0::n], flat[1::n], flat[2::n], ..., flat [n-1::n]
。这些切片作为zip()
函数的参数,将各个元素逐一组合在了一起。
之前讲过zip()
函数会按照最短列表进行截断。在上面的例子中,如果列表长度不是分组因素n
的整数倍,即len(flat) % n != 0
时,最后一个分组的长度将小于前面分组的长度,导致前面的分组被截断,这不是我们想要的结果。
如果改用itertools.zip_longest()
方法,最后的分组长度不足的部分会被None
值补齐,保证所有分组的长度为n
。某些情况下,这些补充值可以接受,而某些情况下我们不希望函数返回这些补充值。
列表切片方法为解决一维列表结构化问题提供了另一种实现方式。作为一种通用实现方法,相比之前的实现,它的优点并不明显。作为将一维列表转换为二元组的实现方法,它的最大优点是简洁。