zip()的作用
先看一下语法:
zip(iter1 [,iter2 [...]]) -> zip object
Python 的内置 help()模块提供了一个简短但又有些令人困惑的解释:
返回一个元组迭代器, 其中第 i 个元组包含每个参数序列或可迭代对象中的第 i 个元素. 当最短的可迭代输入耗尽时, 迭代器将停止. 使用单个可迭代参数, 它将返回 1 元组的迭代器. 没有参数, 它将返回一个空的迭代器.
与往常一样, 当您精通更一般的计算机科学和 Python 概念时, 此模块非常有用. 但是, 对于初学者来说, 这段话只会引发更多问题. 让我们尝试通过示例, 代码片段和可视化来解释 zip()功能:
从许多迭代中获取元素, 然后...... 放在一起
我们可以通过几个列表来演示 zip()的功能:
- uppercase = ['A', 'B', 'C']
- lowercase = ['a', 'b', 'c']
- for x, y in zip(uppercase, lowercase):
- print(x, y)
输出:
A a B b C c
但是, 不限于两个可迭代对象作为参数传递 - 我们可以添加任意多个:
- uppercase = ['A', 'B', 'C']
- lowercase = ['a', 'b', 'c']
- numbers = [1, 2, 3]
- for x, y, z in zip(uppercase, lowercase, numbers):
- print(x, y, z)
这将输出:
A a 1 B b 2 C c 3
让我们直观地看一下该 zip()函数在 Python 中的工作方式:
zip()函数的另一个重要警告是如果各个迭代器的元素个数不一致, 则返回列表长度与最短的对象相同:
- uppercase = ['A', 'B', 'C', 'D', 'E']
- lowercase = ['a', 'b', 'c', 'd']
- numbers = [1, 2, 3]
- for x, y, z in zip(uppercase, lowercase, numbers):
- print(x, y, z)
输出:
A a 1 B b 2 C c 3
正如我们所看到的, 即使列出了三个三元组, uppercase 和 lowercase 列表具有 5 和 4 个元素.
要知道的重要一件事是 zip()函数返回什么.
尽管似乎在调用此函数时会得到一个列表, 但实际上它返回一个称为 zip object 的特殊数据类型, 这意味着使用索引将无法浏览, 下面我们学习如何将其转换为其他数据类型(例如列表).
在此之前, 我们还应再来学习一下迭代 (Iteration), 迭代器对象(iterable), 迭代器(iterator ) 的概念:
Iteration 是计算机科学的通用术语. 它是指对一组元素执行一项操作, 一次执行一个元素. 一个很好的例子是循环 - 它适用于每个单独的项目, 直到整个项目集运行完毕为止.
Iterable 是可以遍历的对象(译者注: 在 Python 中所有东西都是 object, 比如说变量, 容器, 类),iterable 是可以产生 iterator 的 object.
iterator 是表示数据流的对象, 它一次返回一个元素的数据. 它还会记住其在迭代过程中的位置. 本质上, 它控制应如何迭代可迭代对象.
将 zip()对象转换为列表(并使用索引)
zip()函数返回一个 zip 对象 (类似于 map() 操作方式).
zip 对象提供了一些有趣的功能 (迭代速度比 list 更快), 但是我们经常需要将其转换为 list. 为了做到这一点, 我们需要调用 list() 函数:
- b = ["red", "green", "blue"]
- c = ["leopard", "cheetah", "jaguar"]
- print(list(zip(b, c)))
输出:
[('red', 'leopard'), ('green', 'cheetah'), ('blue', 'jaguar')]
list()函数将 zip 对象转换为一个元组列表. 我们可以使用索引浏览各个元组. 出于可读性考虑, 我们首先将新列表分配给一个变量:
- b = ["red", "green", "blue"]
- c = ["leopard", "cheetah", "jaguar"]
- new_list = list(zip(b, c))
- print(new_list[0])
- print(new_list[1])
- print(new_list[2])
这将输出:
- ('red', 'leopard')
- ('green', 'cheetah')
- ('blue', 'jaguar')
将 zip()对象转换成字典
另外, 该 dict()函数可用于将 zip 对象转换为字典. 需要注意的是, 只能使用两个 zip()参数 - 前者产生 key, 后者产生 value:
- b = ["red", "green", "blue"]
- f = ["strawberry", "kiwi", "blueberry"]
- print(dict(zip(b, f)))
输出:
{'red': 'strawberry', 'green': 'kiwi', 'blue': 'blueberry'}
解压列表
在某些情况下, 我们需要执行相反的操作 -- 解压迭代器. 解压操作涉及将压缩后的元素恢复为其原始状态. 为此, 我们添加 * 运算符到函数调用中. 例:
- a = [1, 2, 3]
- b = [4, 5, 6]
- zipped = zip(a, b)
- list(zipped)
- a2, b2 = zip(*zip(a, b))
- print(a == list(a2) and b == list(b2))
输出:
True
Zip 与列表生成式(for 循环潜在问题)
zip()函数与 Python 中的 for 循环一起使用的可视化
在应用 for 循环后注意缺少的元素!
Python 的另一个很棒的功能 -- 列表推导式, 可以与 zip()函数结合使用. 表面上看起来很简单......
- m = ["mind", "mouse", "mini"]
- n = ["norm", "night", "necklace"]
- [print(a, b) for a, b in zip(m, n)]
输出:
- mind norm
- mouse night
- mini necklace
看起来很简单, 似乎没有任何错误, 对吗? 是的
如果我们想 a 从列表生成式获取参数并打印出来, 我们得到 a NameError 的报错提示, 这是完全正常的, 因为 a 在列表推导之外不是实数:
- Traceback (most recent call last):
- File "C:\Pro\Py\tp-ex\tmp1.py", line 5, in
- print(a)
- NameError: name 'a' is not defined
但是, 如果我们决定使用 for 循环而不是列表生成式, 然后打印 a, 我们会得到一些奇怪的结果. 请记住, for 循环输出的结果与列表生成式的结果相同.
- m = ["mind", "mouse", "mini"]
- n = ["norm", "night", "necklace"]
- for m, n in zip(m, n):
- print(m, n)
- print(m)
结果输出是...
- mind norm
- mouse night
- mini necklace
- mini
等等, 叛逆的 mini 在这里干什么? 事实证明, m 先前引用的列表变量 "mind", "mouse", "mini" 被覆盖了! 因此, 应该牢记列表生成式和 for 循环的运行方式完全不同.
结论
好吧, 事实证明, zip()函数在 Python 中确实有一些窍门!与往常一样, 鼓励大家实际使用我们的代码示例, 而不仅是阅读本文. 如果您与代码进行交互并对其进行调整, 则肯定会遇到一些独特的问题 - 解决它们将帮助大家更好地掌握知识.
翻译: 爱学习的胡同学
来源: https://www.cnblogs.com/jpld/p/12315738.html