定義
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中文網其他相關文章!