4.4Python语言的迭代器(iterator)类型和生成器(generator)类型

iterate(迭代或遍历)

​ (1)如果想要一个对象成为可迭代对象,也就是说使用Class类实例出来的对象可以直接使用for循环遍历,那么这个对象中必须实现一个方法__iter__。

​ (2)如果想让一个可迭代对象成为迭代器,则将必须继续使用__next__方法,那么也就是说成为迭代器的条件为实 现 __iter__和__next__方法,二者缺一不可。

​ (3) __iter__方法是可迭代对象的核心方法,它每次返回一个迭代器即自身,那么也就是说每次真正迭代的核心控制者是迭代器。

​ (4)而__next__方法的作用就是返回每次迭代的最终数据,也是迭代器每次进行迭代工作的最终结果。

​ (5)在__next__方法中引发一个StopIteration 异常,是迭代结束的标志,也就是终止迭代。

iterable(可迭代对象)

可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

for循环的本质就是先通过__iter__这个方法获取可迭代对象的迭代器,然后对获取的迭代器进行不断调用__next_方法,来获取下一个值,并将其赋值给临时变量i就是in前边的那个临时变量,当遇到StopIteration异常对象则终止循环。

iterator(迭代器)

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

dict迭代

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
...     print(key)
...
a
c
b

因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()

生成器(generator)

生成器是一个相对较新的Python概念。由于历史原因,它也被称为简单生成器( simple
generator)。生成器和迭代器可能是近年来引入的最强大的功能,但生成器是一个相当复杂的概
念,你可能需要花些功夫才能明白其工作原理和用途。虽然生成器让你能够编写出非常优雅的代
码,但请放心,无论编写什么程序,都完全可以不使用生成器。
生成器是一种使用普通函数语法定义的迭代器。生成器的工作原理到底是什么呢?通过示例
来说明最合适。下面先来看看如何创建和使用生成器,然后再看看幕后的情况。

生成器创建起来与函数一样简单。你现在肯定厌烦了老套的斐波那契数列,所以下面换换口
味,创建一个将嵌套列表展开的函数。这个函数将一个类似于下面的列表作为参数:

nested = [[1, 2], [3, 4], [5]]

换而言之,这是一个列表的列表。函数应按顺序提供这些数字,下面是一种解决方案:

def flatten(nested):
for sublist in nested:
for element in sublist:
yield element

在这里,你没有见过的是yield语句。包含yield语句的函数都被称为生成器。这可不仅仅是
名称上的差别,生成器的行为与普通函数截然不同。差别在于,生成器不是使用return返回一个
值,而是可以生成多个值,每次一个。每次使用yield生成一个值后,函数都将冻结,即在此停
止执行,等待被重新唤醒。被重新唤醒后,函数将从停止的地方开始继续执行。
为使用所有的值,可对生成器进行迭代。

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/python/pythonbasic/2741.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注