定义
class Iterable(metaclass=ABCMeta): __slots__ = () @abstractmethod def __iter__(self): while False: yield None @classmethod def __subclasshook__(cls, C): if cls is Iterable: if any("__iter__" in B.__dict__ for B in C.__mro__): return True return NotImplemented
由定义可知Iterable
必然包含__iter__
函数
定义
class Iterator(Iterable): __slots__ = () @abstractmethod def __next__(self): 'Return the next item from the iterator. When exhausted, raise StopIteration' raise StopIteration def __iter__(self): return self @classmethod def __subclasshook__(cls, C): if cls is Iterator: if (any("__next__" in B.__dict__ for B in C.__mro__) and any("__iter__" in B.__dict__ for B in C.__mro__)): return True return NotImplemented
从定义可知Iterator
包含__next__
和__iter__
函数,当next超出范围时将抛出StopIteration
事件
类型关系
#! /usr/bin/python #-*-coding:utf-8-*- from collections import Iterator,Iterable # 迭代器 s = 'abc' l = [1,2,3] d=iter(l) print(isinstance(s,Iterable)) # True print(isinstance(l,Iterable)) # True print(isinstance(s,Iterator)) # False print(isinstance(l,Iterator)) # False print(isinstance(d,Iterable)) # True print(isinstance(d,Iterator)) # True
理论上你可以使用next()
来执行__next__()
,直到迭代器抛出StopIteration
实际上系统提供了for .. in ..
的方式来解析迭代器
l = [1,2,3,4] for i in l: print(i) # 执行结果 # 1 # 2 # 3 # 4
生成器的本质是一个迭代器
#! /usr/bin/python #-*-coding:utf-8-*- from collections import Iterator,Iterable s = (x*2 for x in range(5)) print(s) print('Is Iterable:' + str(isinstance(s,Iterable))) print('Is Iterator:' + str(isinstance(s,Iterator))) for x in s: print(x) # 执行结果 # <generator object <genexpr> at 0x000001E61C11F048> # Is Iterable:True # Is Iterator:True # 0 # 2 # 4 # 6 # 8
函数中如果存在yield
则该函数是一个生成器对象 在每一次执行next
函数时该函数会在上一个yield
处开始执行,并在下一个yield
处返回(相当于return
)
def foo(): print("First") yield 1 print("Second") yield 2 f = foo() print(f) a = next(f) print(a) b = next(f) print(b) # <generator object foo at 0x0000020B697F50F8> # First # 1 # Second # 2
实例
#! /usr/bin/python #-*-coding:utf-8-*- def add(s,x): return s+x def gen(): for i in range(4): yield i base = gen() # 由于gen函数中存在yield,所以 # for 循环本质是创建了两个generator object,而非执行函数 # base = (add(i,10) for i in base) # base = (add(i,10) for i in base) for n in [1,10]: base = (add(i,n) for i in base) # 这里才开始展开生成器 # 第一个生成器展开 # base = (add(i,10) for i in base) # base = (add(i,10) for i in range(4)) # base = (10,11,12,13) # # 第二个生成器展开 # base = (add(i,10) for i in (10,11,12,13)) # base = (20,21,22,23) print(list(base)) # [20,21,22,23]
以上是Python中迭代器和生成器的示例详解的详细内容。更多信息请关注PHP中文网其他相关文章!