迭代器与可迭代对象的区别?

8

(适用于Python 3)

在Python文档中,您可以看到list()函数接受一个可迭代对象。

在Python文档中,您还可以看到next()函数接受一个迭代器。

因此,在IDLE中我这样做:

>>> var = map(lambda x: x+5, [1,2,3])
>>> var
>>> next(v)
>>> list(v)

这将输出:

<map object at 0x000000000375F978>
6
[7,8]

坦白说,这不是我预期的。地图对象是迭代器还是可迭代对象?它们有什么区别吗?显然,无论地图对象是什么,list()next()函数都可以使用。

为什么它们都能用?


Python文档称map的结果始终为列表,但考虑到您的结果,这似乎有些奇怪。 - Lasse V. Karlsen
2
不适用于Python 3。 (http://docs.python.org/3/library/functions.html#map) - temporary_user_name
1
你说得对。在Python 3中,它说“返回一个迭代器”,所以你已经得到了答案。我只是进行了一次谷歌搜索并使用了第一个结果,没有检查版本。 - Lasse V. Karlsen
1
在Python 3中,大多数这些函数,例如rangefiltermap等,开始返回迭代器。这样更节省内存(不再有xrange)。 - daniel gratzer
1个回答

23

迭代器是可迭代的,但可迭代的不一定是迭代器。

可迭代的是指任何定义了__iter__方法的对象,例如列表和元组,以及迭代器本身。

迭代器是可迭代对象的一个子集,其值不能同时全部访问,因为它们并未全部存储在内存中。可以使用诸如mapfilteriter等函数来生成这些迭代器,也可以使用使用yield的函数。

在您的示例中,map返回一个迭代器,它也是一个可迭代对象,这就是为什么这两个函数都可以使用它的原因。然而,如果我们以列表为例:

>>> lst = [1, 2, 3]
>>> list(lst)
[1, 2, 3]
>>> next(lst)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    next(lst)
TypeError: 'list' object is not an iterator

我们可以看到next报错,因为列表是可迭代的,但不是迭代器


10
迭代器是可迭代对象的子集,其值不能同时全部访问,因为它们并未一次全部存储在内存中。这完全是错误的。例如,如果您在2025年之前阅读此内容,则 python 3 的 range(1000000000000000000) 可迭代对象的值无法适合您笔记本电脑的内存。然而,该可迭代对象不是迭代器。正确的定义是 "迭代器是具有next方法的可迭代对象的子集。" - max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接