探索Python的zip()函数:简化迭代和数据组合

Python的zip()函数:简化迭代和数据组合

初学者指南:使用zip()在Python中优化数据操作和迭代,提高效率和生产力

Tomas Sobek在Unsplash上的照片

介绍

zip()是Python标准解释器中的内置函数。它是一个强大的方法,可以更轻松地处理字典和列表等可迭代对象。

在本文中,我们将探讨zip函数的语法和工作原理,以便在实际情况中掌握如何使用该方法。

语法

根据Python文档的一般函数定义:

zip(*iterables, strict=False)

根据定义,该方法使用*iterables非关键字参数接受任意数量的可迭代对象。因此,我们可以将任意数量的可迭代对象传递给zip函数,这些对象将作为单个参数列表传递。

还有一个我们稍后将探讨的’strict’关键字参数。

用例示例1

为了理解如何使用zip函数,可以查看以下交互式代码片段。

示例1 —— Replit

假设我们有3个不同的列表。一个包含产品,另外两个列表包含销售的产品数量和价格。

如果我们想要计算每个产品的总销售额,我们可以使用简单的for循环来完成。但是,我们将不得不索引每个数组,并处理大小不匹配的边缘情况。而且,该解决方案对于任意数量的可迭代对象来说并不可扩展。

zip函数提供了一个简单的接口来执行此类任务,因为您可以将所有可迭代对象传递给zip函数。

这将返回一个元组的迭代器,其中第i个元组包含每个参数可迭代对象的第i个元素。

因此,在上面的示例中对已压缩的列表进行迭代时,将每个产品与其价格和数量组合在单个元组中。可以在迭代过程中解构此元组以获取值。

运行上面的代码以更好地理解zip函数的工作原理。

用例示例2

这是一个较难的例子。假设我们有一个二维数组,我们想要对列中的所有值求平均值。

使用for循环,我们可以迭代矩阵的行。对于列的平均值,我们将不得不使用嵌套循环分别迭代各列。

zip提供了一种解决方法。

transposed = zip(*matrix)

我们可以通过将所有行作为可迭代对象传递给zip函数来简单地转置矩阵。*运算符用于解包参数,因此它将矩阵解压以进行转置。

column_averages = [sum(column) / len(column) for column in transposed]

然后,我们可以迭代来自已压缩的可迭代对象的每一列,以计算列的平均值。

如何解压可迭代对象

现在我们对zip和*运算符都有了了解,我们可以将两者结合起来反转zip函数。

一旦我们将一些可迭代对象压缩在一起,我们可以通过解压所有已压缩的元组,然后再将它们压缩在一起来恢复它们。

逐步进行如下:

products = ['苹果', '香蕉', '樱桃']prices = [1.5, 0.75, 2.25]quantities = [10, 15, 5]# 使用zip()组合列表sales = zip(products, prices, quantities)

我们首先展开可迭代对象,这将创建类似于上面的转置矩阵示例的新可迭代对象。

print(*sales)# 输出# ('苹果', 1.5, 10) ('香蕉', 0.75, 15) ('樱桃', 2.25, 5)

我们现在可以将它们一起压缩,使得第一个位置上的所有元素都是第一个可迭代对象的成员,第二个位置上的所有元素都是第二个可迭代对象的成员,依此类推。

需要注意的是,一旦你迭代了一个zip对象,它就会被耗尽,也就是说这个zip对象变为空。

因此,我们可以使用一行简洁的代码来完成这个操作:

products, prices, quantities = zip(*sales)

严格关键字参数

默认情况下,zip函数允许不同大小的可迭代对象。如果传递的可迭代对象大小不同,那么只有最短的可迭代对象的元素会被压缩。

list(zip(range(3), ['fee', 'fi', 'fo', 'fum']))# 输出 [(0, 'fee'), (1, 'fi'), (2, 'fo')]

然而,大多数情况下,zip函数被用于大小相同的可迭代对象。为了确保这种限制,我们可以传递strict=True。这将在可迭代参数之间存在大小匹配时引发ValueError。

使用Zip的好处

内存高效

Zip是惰性的。在迭代过程中,可迭代对象是即时生成的。因此,不需要创建一个新的列表来存储压缩后的可迭代对象。

灵活性

Zip可以与各种可迭代对象一起使用,如列表、字典、元组和字符串。它甚至可以与用户定义的类一起使用。你只需要在Python中实现__iter__的特殊方法就可以了。下面是一个代码示例。

class Person:    def __init__(self, name, age):        self.name = name        self.age = age        def __iter__(self):        return iter([self.name, self.age])# 创建Person类的实例person1 = Person("John", 30)person2 = Person("Alice", 25)person3 = Person("Bob", 35)# 压缩Person对象zipped = zip(person1, person2, person3)# 迭代压缩对象并打印元素for item in zipped:    print(item)

结论

zip函数是一个多功能的函数,可以通过简化的代码结构实现同时迭代。它可以与map、filter和reduce函数结合使用,以使用少量的代码实现复杂的数据操作。

如果你喜欢这篇文章,关注我获取更多关于Python和机器学习领域的文章。