python - 关于 Python 中迭代器和可迭代对象的困惑

标签 python python-3.x iterator documentation iterable

我目前正在阅读 Python 3.5 的官方文档。

它指出 range() 是可迭代的,而 list()for 是迭代器。 [section 4.3]

然而,here它声明 zip() 生成了一个迭代器。

我的问题是,当我们使用这条指令时:

list(zip(list1, list2))

我们是否使用迭代器 (list()) 来迭代另一个迭代器?

最佳答案

文档在这里通过重新使用术语“迭代器”造成了一些困惑。

iterator protocol 包含三个组成部分:

  1. 可迭代对象;您可以可能迭代并逐一获取其元素的事物。

  2. 迭代器;进行迭代的事情。每次你想遍历一个可迭代对象的所有项目时,你都需要其中一个来跟踪你在这个过程中的位置。这些不可重复使用;一旦你到达终点,就是这样。对于大多数可迭代对象,您可以创建多个独立的迭代器,每个迭代器独立跟踪位置。

  3. 迭代器的消费者;那些想要对元素做些什么的人。

for 循环是后者的一个例子,所以#3。 for 循环使用 iter() function为您想要循环的任何内容生成一个迭代器(上面的#2),因此“whatever”必须是可迭代的(上面的#1)。

range() 是#1 的例子;它是可迭代的对象。您可以独立地对其进行多次迭代:

>>> r = range(5)
>>> r_iter_1 = iter(r)
>>> next(r_iter_1)
0
>>> next(r_iter_1)
1
>>> r_iter_2 = iter(r)
>>> next(r_iter_2)
0
>>> next(r_iter_1)
2

此处 r_iter_1r_iter_2 是两个独立的迭代器,每次您请求下一个项目时,它们都会根据自己的内部簿记进行操作。

list()可迭代对象 (#1) 和迭代消费者 (#3) 的示例。如果将另一个可迭代对象 (#1) 传递给 list() 调用,则会生成一个包含该可迭代对象中所有元素的列表对象。但是列表对象本身也是可迭代的。

zip(),在 Python 3 中,接收多个可迭代对象 (#1),并且它本身是一个迭代器 (#2)。 zip() 为您提供的每个可迭代对象存储一个新的迭代器 (#2)。每次您向 zip() 请求下一个元素时,zip() 都会使用来自每个包含的可迭代对象的下一个元素构建一个新元组:

>>> lst1, lst2 = ['foo', 'bar'], [42, 81]
>>> zipit = zip(lst1, lst2)
>>> next(zipit)
('foo', 42)
>>> next(zipit)
('bar', 81)

所以最后,list(zip(list1, list2)) 同时使用 list1list2 作为迭代(#1),当 zip() 本身被外部 list() 调用消耗时,它会消耗那些 (#3)。

关于python - 关于 Python 中迭代器和可迭代对象的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40650082/

相关文章:

python - 在映射函数中除以 0

Python Regex 在 3 个在线测试人员上成功测试,但在代码中不起作用

python-3.x - 如何修复迭代 pandas 分组 df 时的 ValueError?

python - Pandas如何通过在每列的任何行中获取值='yes'来组合行分组名称

c++ - 将指针传递给 vector 的第一个元素(如果有)

python - 在调用打印函数时增加一个变量

python - 如何使用 re.DOTALL 跨多行文本搜索正则表达式模式?

c++ - 迭代器和整数的减法

php - 在多维数组中搜索键并返回它的路径

python - 为什么用 StopIteration Exception 实现迭代的结束