迭代器和生成器有什么区别?当您使用每个案例的时候,一些示例将是有帮助的。
总之:迭代器是具有__iter__和一个__next__ (next在Python 2)方法中。生成器提供了一种简单、内置的方法来创建迭代器的实例。
其中包含产额的函数仍然是一个函数,当被调用时,该函数返回生成器对象的实例:def a_function():
"when called, returns generator object"
yield
生成器表达式还返回生成器:a_generator = (i for i in range(0))
要获得更深入的说明和例子,请继续阅读.
发电机是爱尔兰人
具体来说,生成器是迭代器的一个子类型。>>> import collections, types>>> issubclass(types.GeneratorType, collections.Iterator)True
我们可以通过多种方式创建一个生成器。一个非常常见和简单的方法是使用函数。
具体来说,其中包含产额的函数是一个函数,当被调用时,它返回一个生成器:>>> def a_function():
"just a function definition with yield in it"
yield>>> type(a_function)>>> a_generator = a_function() # when called>>> type(a_generator)
# returns a generator
同样,发电机也是一个迭代器:>>> isinstance(a_generator, collections.Iterator)True
爱尔兰人是易碎的
一个爱尔兰人是一个可学的人,>>> issubclass(collections.Iterator, collections.Iterable)True
这需要一个__iter__方法返回一个Iterator:>>> collections.Iterable()Traceback (most recent call last):
File "", line 1, in
collections.Iterable()TypeError: Can't instantiate abstract class Iterable with abstract methods __iter__
迭代的一些例子是内置元组、列表、字典、集、冻结集、字符串、字节数组、范围和内存视图:>>> all(isinstance(element, collections.Iterable) for element in (
(), [], {}, set(), frozenset(), '', b'', bytearray(), range(0), memoryview(b'')))True
迭代器要求 a next或__next__方法
在Python 2中:>>> collections.Iterator()Traceback (most recent call last):
File "", line 1, in
collections.Iterator()TypeError: Can't instantiate abstract class Iterator with abstract methods next
在Python 3中:>>> collections.Iterator()Traceback (most recent call last):
File "", line 1, in TypeError: Can't instantiate abstract class Iterator with abstract methods __next__
我们可以从内置对象(或自定义对象)获得迭代器。iter职能:>>> all(isinstance(iter(element), collections.Iterator) for element in (
(), [], {}, set(), frozenset(), '', b'', bytearray(), range(0), memoryview(b'')))True
这个__iter__方法在尝试使用带for-循环的对象时调用。然后__next__方法在迭代器对象上调用,以获取循环中的每个项。迭代器引发StopIteration当你用尽它时,它就不能再使用了。
从文件中
从“迭代器类型”的“生成器类型”部分中,到“内置类型”的“生成器类型”部分。文献资料:Python的生成器为实现迭代器协议提供了一种方便的方法。如果容器对象的__iter__()方法作为生成器实现,它将自动返回迭代器对象(从技术上讲,是生成器对象),提供__iter__()和next() [__next__()在Python 3]方法中。有关生成器的更多信息可以在产率表达式的文档中找到。
(强调后加)
因此,我们从中了解到,生成器是一种(方便的)类型的迭代器。
示例Iterator对象
您可以通过创建或扩展自己的对象来创建实现Iterator协议的对象。class Yes(collections.Iterator):
def __init__(self, stop):
self.x = 0
self.stop = stop def __iter__(self):
return self def next(self):
if self.x < self.stop:
self.x += 1
return 'yes'
else:
# Iterators must raise when done, else considered broken
raise StopIteration
__next__ = next # Python 3 compatibility
但是,简单地使用生成器来完成以下操作就更容易了:def yes(stop):
for _ in range(stop):
yield 'yes'
或者更简单一些,生成器表达式(类似于列表理解):yes_expr = ('yes' for _ in range(stop))
它们都可以同样的方式使用:>>> stop = 4 >>> for i, y1, y2, y3 in zip(range(stop), Yes(stop), yes(stop),
('yes' for _ in range(stop))):...
print('{0}: {1} == {2} == {3}'.format(i, y1, y2, y3))...
0: yes == yes == yes1: yes == yes == yes2: yes == yes == yes3: yes == yes == yes
结语
当需要将Python对象扩展为可以迭代的对象时,可以直接使用Iterator协议。
然而,在绝大多数情况下,您最适合使用yield若要定义返回生成器迭代器或考虑生成器表达式的函数,请执行以下操作。