Python 中的 zip() 函数

Vaibhav Vaibhav 2022年5月18日
Python 中的 zip() 函数

在 Python 和所有编程语言中,我们可以使用 forwhile 循环来迭代数组。迭代单个数组非常简单。然而,当涉及到一起迭代多个数组时,事情开始变得复杂。如果所有数组的大小都相同,那么这是一项简单的工作。但是如果数组大小不同,我们必须确保只考虑最小数组的长度,以避免错误和异常。

Python 使这项任务变得容易得多。我们可以使用 Python 提供的内置实用程序,更准确地说是一个函数,而不是手动编写用于迭代不同大小数组的逻辑。这个函数是 zip() 函数。

本文将介绍 zip() 函数及其使用方法。

Python 中的 zip() 函数

zip() 函数接受可迭代对象(例如列表、字符串和元组)作为参数并返回单个可迭代对象。

返回的可迭代对象具有最小可迭代对象的长度。例如,如果将两个大小为 510 的列表提供给 zip() 函数,则返回的可迭代对象将具有 5 的长度。这意味着只有第二个列表的前 5 个元素将成为可迭代对象的一部分。如果给这个函数一个空的可迭代对象或没有可迭代对象,它也返回一个空的可迭代对象。

现在我们已经完成了理论,让我们看看如何使用这个功能。请参阅以下示例以了解其用法。

没有可迭代对象

在以下 Python 代码中,不会将任何可迭代对象传递给 zip() 函数。

result = zip()

for x in result:
    print(x)

当我们执行上述代码时,控制台上不会打印任何内容。背后的原因很简单;如果没有提供可迭代对象,我们将没有可迭代的内容。因此,返回一个空的可迭代对象。

相同长度的可迭代对象

在下面的 Python 代码中,一个整数元组、一个浮点值列表、一个类对象列表和一个相等长度的字符串将被传递给 zip() 函数。

class Number:
    def __init__(self, number):
        self.number = number

    def square(self):
        return number ** 2

    def __repr__(self):
        return f"Number({self.number})"


a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)

for x in result:
    print(x)

输出:

(11, 1.1, Number(1), 'H')
(22, 2.2, Number(23), 'e')
(33, 3.3, Number(44.44), 'l')
(44, 4.4, Number(0), 'l')
(55, 5.5, Number(-9), 'o')

正如我们所见,zip() 函数将所有可迭代对象的值一起存储在元组中。元组中值的顺序与将它们的可迭代对象提供给 zip() 函数的顺序相同。

我们可以在 for 循环中解构或解压缩这些值以便于访问。请参阅以下代码。

class Number:
    def __init__(self, number):
        self.number = number

    def square(self):
        return number ** 2

    def __repr__(self):
        return f"Number({self.number})"


a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)

for p, q, r, s in result:
    print("A:", p)
    print("B:", q)
    print("C:", r)
    print("D:", s)

输出:

A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l
A: 44
B: 4.4
C: Number(0)
D: l
A: 55
B: 5.5
C: Number(-9)
D: o

除了使用 for 循环,我们还可以使用 while 循环对可迭代对象进行迭代。使用 while 循环,我们需要两个额外的东西,next() 函数和 try-except 块。next() 函数将用于从 zip() 函数返回的可迭代对象中获取值,try...except 块将用于停止迭代。请参阅以下 Python 代码。

class Number:
    def __init__(self, number):
        self.number = number

    def square(self):
        return number ** 2

    def __repr__(self):
        return f"Number({self.number})"


a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)

while True:
    try:
        p, q, r, s = next(result)
        print("A:", p)
        print("B:", q)
        print("C:", r)
        print("D:", s)
    except StopIteration:
        break

输出:

A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l
A: 44
B: 4.4
C: Number(0)
D: l
A: 55
B: 5.5
C: Number(-9)
D: o

当迭代器内没有可用值时,它会引发 StopIteration 异常。使用 try-except 块,我们捕获此异常并退出无限 while 循环。

不同长度的可迭代对象

在下面的 Python 代码中,整数元组、浮点值列表、类对象列表和不同长度的字符串将传递给 zip() 函数。

class Number:
    def __init__(self, number):
        self.number = number

    def square(self):
        return number ** 2

    def __repr__(self):
        return f"Number({self.number})"


a = (11, 22, 33)
b = [1.1, 2.2, 3.3, 4.4]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "HelloWorld"
result = zip(a, b, c, d)

for p, q, r, s in result:
    print("A:", p)
    print("B:", q)
    print("C:", r)
    print("D:", s)

输出:

A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l

所有可迭代对象都有不同的长度。第一个可迭代对象或整数元组的长度最小,3。因此,输出仅打印所有可迭代对象的前 3 个值。

创建字典

我们可以在 zip() 函数的帮助下创建一个键值对字典。这个想法是创建两个长度相同的数组的迭代器,包含键和它们各自的值,并在迭代返回的可迭代对象时将它们映射到字典中。请参阅以下代码。

import json

a = ["W", "O", "R", "L", "D"]
b = [1.1, True, "Hello", None, 5]
result = zip(a, b)
mapping = {x: y for x, y in result}
print(json.dumps(mapping, indent=4))

输出:

{
    "W": 1.1,
    "O": true,
    "R": "Hello",
    "L": null,
    "D": 5
}

上面的代码只使用了 json 模块来美化字典的输出。请注意,使用它是完全可选的。

zip() 函数与 enumerate() 函数一起使用

enumerate() 函数用于在迭代可迭代对象时同时获取索引和值。由于 zip() 函数返回一个迭代器,我们可以将这两个函数组合在一起并访问索引和值。请参阅以下 Python 代码。

class Number:
    def __init__(self, number):
        self.number = number

    def square(self):
        return number ** 2

    def __repr__(self):
        return f"Number({self.number})"


a = (11, 22, 33)
b = [1.1, 2.2, 3.3, 4.4]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "HelloWorld"
result = zip(a, b, c, d)

for i, (p, q, r, s) in enumerate(result):
    print(f"A{i + 1}:", p)
    print(f"B{i + 1}:", q)
    print(f"C{i + 1}:", r)
    print(f"D{i + 1}:", s)

输出:

A1: 11
B1: 1.1
C1: Number(1)
D1: H
A2: 22
B2: 2.2
C2: Number(23)
D2: e
A3: 33
B3: 3.3
C3: Number(44.44)
D3: l

在上面的 Python 代码中,在 for 循环中,i, (p, q, r, s) 解包 enumerate() 函数返回的值,以及 (p, q, r, s) 解压缩 zip() 函数返回的值。

enumerate() 函数返回的值采用以下格式。

(0, (11, 1.1, Number(1), "H"))
(1, (22, 2.2, Number(23), "e"))
(2, (33, 3.3, Number(44.44), "l"))

它阐明了为什么使用 i, (p, q, r, s) 来解包所有值。

作者: Vaibhav Vaibhav
Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.

相关文章 - Python Function