迭代器,迭代器和迭代究竟是什么?
“iterable”,“iterator”和“Python中的迭代”最基本的定义是什么?
我已经阅读了多个定义,但其确切含义仍然不会沉入其中。
有人可以帮助我的基本想法吗?
迭代是一个接一个地接受每件事物的总称。 任何时候你使用循环,显式或隐式,遍历一组项目,这是迭代。
在Python中, iterable和iterator具有特定的含义。
iterable是一个具有__iter__
方法的对象,该方法返回一个迭代器 ,或者定义一个可以从零开始的连续索引的__getitem__
方法(并且在索引不再有效时引发IndexError
)。 所以一个迭代器是一个可以从中获取迭代器的对象。
迭代器是一个包含next
(Python 2)或__next__
(Python 3)方法的对象。
无论何时在Python中使用for
循环, map
或列表理解等,都会自动调用next
方法以从迭代器中获取每个项目,从而遍历迭代过程。
开始学习的好地方是本教程的迭代器部分和标准类型页面的迭代器类型部分。 了解基础知识后,请尝试Functional Programming HOWTO的迭代器部分。
以下是我在教授Python类时使用的解释:
ITERABLE是:
for x in iterable: ...
或者 iter()
调用的函数都会返回一个ITERATOR: iter(obj)
或者 __iter__
的对象,或者它可能有一个适用于索引查找的__getitem__
方法。 ITERATOR是一个对象:
__next__
方法: StopIteration
完成信号 self
的__iter__
方法)。 笔记:
__next__
在Python 3方法的拼写next
在Python 2,和 next()
在传递给它的对象上调用该方法。 例如:
>>> s = 'cat' # s is an ITERABLE
# s is a str object that is immutable
# s has no state
# s has a __getitem__() method
>>> t = iter(s) # t is an ITERATOR
# t has state (it starts by pointing at the "c"
# t has a next() method and an __iter__() method
>>> next(t) # the next() function returns the next value and advances the state
'c'
>>> next(t) # the next() function returns the next value and advances
'a'
>>> next(t) # the next() function returns the next value and advances
't'
>>> next(t) # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration
>>> iter(t) is t # the iterator is self-iterable
上述答案很好,但就我看到的大部分内容而言,不要强调像我这样的人的区别。
另外,人们往往会通过将诸如“X是一个具有__foo__()
方法的对象”之类的定义放在之前,来获得“太Pythonic”。 这样的定义是正确的 - 它们是基于鸭子打字的哲学,但当试图以简单的方式理解概念时,对方法的关注往往会介于两者之间。
所以我添加我的版本。
在自然语言中,
在Python中,
iterable是一个可迭代的对象,简单地说,它意味着它可以在迭代中使用,例如用for
循环。 怎么样? 通过使用迭代器。 我会在下面解释。
...而迭代器是一个定义如何实际进行迭代的对象 - 具体来说,下一个元素是什么。 这就是为什么它必须有next()
方法。
迭代器本身也是可迭代的,不同之处在于它们的__iter__()
方法返回相同的对象( self
),而不管它的项是否已被以前对next()
调用所消耗。
那么Python解释器for x in obj:
statement中看到for x in obj:
时会怎么想呢?
看,一个for
循环。 看起来像一个迭代器的工作...让我们得到一个。 ...有这个obj
人,所以让我们问他。
“ obj
先生,你有你的迭代器吗?” (...调用iter(obj)
,它调用obj.__iter__()
,它愉快地发出一个闪亮的新迭代器_i
。)
好吧,那很简单...让我们开始迭代吧。 ( x = _i.next()
... x = _i.next()
...)
因为obj
先生在这个测试中成功了(通过某种方法返回一个有效的迭代器),我们用形容词来奖励他:现在你可以称他为“可迭代先生obj
”。
然而,在简单的情况下,你通常不会分别获得迭代器和迭代器的好处。 所以你只定义一个对象,这也是它自己的迭代器。 (Python并不真正关心由obj
_i
不是那么闪亮,而只是obj
本身。)
这就是为什么在我见过的大多数例子中(以及让我一遍又一遍困惑的东西),你可以看到:
class IterableExample(object):
def __iter__(self):
return self
def next(self):
pass
代替
class Iterator(object):
def next(self):
pass
class Iterable(object):
def __iter__(self):
return Iterator()
但是,有些情况下,当你可以从迭代器中分离出迭代器时,比如当你想要有一行项目,但是有更多的“光标”时,你就可以受益。 例如,当你想使用“当前”和“即将到来”的元素时,你可以为两者分别设置迭代器。 或者从一个巨大的列表中拉出多个线程:每个线程都可以有自己的迭代器遍历所有项目。 请参阅上面的@ Raymond's和@ glglgl的答案。
想象一下你可以做什么:
class SmartIterableExample(object):
def create_iterator(self):
# An amazingly powerful yet simple way to create arbitrary
# iterator, utilizing object state (or not, if you are fan
# of functional), magic and nuclear waste--no kittens hurt.
pass # don't forget to add the next() method
def __iter__(self):
return self.create_iterator()
笔记:
我会再次重复一遍:迭代器不可迭代。 迭代器不能被用作“源” for
环。 什么for
循环主要需要的是__iter__()
返回的东西next()
当然, for
不是唯一的迭代循环,所以以上也适用于其他一些结构( while
...)。
迭代器的next()
可以抛出StopIteration来停止迭代。 不过,它可以永久迭代或使用其他方法。
在上述“思考过程”中, _i
并不存在。 我已经制定了这个名字。
Python 3.x有一个小小的变化: next()
方法(不是内置的)现在必须被称为__next__()
。 是的,它应该一直如此。
你也可以这样想:迭代器有数据,迭代器拉下一个项目
免责声明:我不是任何Python解释器的开发人员,所以我不知道解释器“认为”什么。 上面的思考仅仅证明了我是如何从Python新手的其他解释,实验和实际经验中理解这个话题的。
链接地址: http://www.djcxy.com/p/54785.html