迭代器与生成器
Posted 绝望的老猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器与生成器相关的知识,希望对你有一定的参考价值。
迭代器
Iterable
定义
1 class Iterable(metaclass=ABCMeta): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __iter__(self): 7 while False: 8 yield None 9 10 @classmethod 11 def __subclasshook__(cls, C): 12 if cls is Iterable: 13 if any("__iter__" in B.__dict__ for B in C.__mro__): 14 return True 15 return NotImplemented
由定义可知Iterable
必然包含__iter__
函数
Iterator
定义
1 class Iterator(Iterable): 2 3 __slots__ = () 4 5 @abstractmethod 6 def __next__(self): 7 ‘Return the next item from the iterator. When exhausted, raise StopIteration‘ 8 raise StopIteration 9 10 def __iter__(self): 11 return self 12 13 @classmethod 14 def __subclasshook__(cls, C): 15 if cls is Iterator: 16 if (any("__next__" in B.__dict__ for B in C.__mro__) and 17 any("__iter__" in B.__dict__ for B in C.__mro__)): 18 return True 19 return NotImplemented
从定义可知Iterator
包含__next__
和__iter__
函数,当next超出范围时将抛出StopIteration
事件
类型关系
1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3 4 from collections import Iterator,Iterable 5 6 # 迭代器 7 s = ‘abc‘ 8 l = [1,2,3] 9 d=iter(l) 10 11 print(isinstance(s,Iterable)) # True 12 print(isinstance(l,Iterable)) # True 13 14 print(isinstance(s,Iterator)) # False 15 print(isinstance(l,Iterator)) # False 16 17 print(isinstance(d,Iterable)) # True 18 print(isinstance(d,Iterator)) # True
理论上你可以使用next()
来执行__next__()
,直到迭代器抛出StopIteration
实际上系统提供了for .. in ..
的方式来解析迭代器
1 l = [1,2,3,4] 2 for i in l: 3 print(i) 4 5 # 执行结果 6 # 1 7 # 2 8 # 3 9 # 4
生成器 generator
生成器的本质是一个迭代器
1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3 4 from collections import Iterator,Iterable 5 6 s = (x*2 for x in range(5)) 7 print(s) 8 print(‘Is Iterable:‘ + str(isinstance(s,Iterable))) 9 print(‘Is Iterator:‘ + str(isinstance(s,Iterator))) 10 11 for x in s: 12 print(x) 13 14 # 执行结果 15 # <generator object <genexpr> at 0x000001E61C11F048> 16 # Is Iterable:True 17 # Is Iterator:True 18 # 0 19 # 2 20 # 4 21 # 6 22 # 8
函数中如果存在yield
则该函数是一个生成器对象 在每一次执行next
函数时该函数会在上一个yield
处开始执行,并在下一个yield
处返回(相当于return
)
1 def foo(): 2 print("First") 3 yield 1 4 print("Second") 5 yield 2 6 7 f = foo() 8 print(f) 9 10 a = next(f) 11 print(a) 12 b = next(f) 13 print(b) 14 15 # <generator object foo at 0x0000020B697F50F8> 16 # First 17 # 1 18 # Second 19 # 2
实例
1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3 4 def add(s,x): 5 return s+x 6 7 def gen(): 8 for i in range(4): 9 yield i 10 11 base = gen() 12 13 # 由于gen函数中存在yield,所以 14 # for 循环本质是创建了两个generator object,而非执行函数 15 # base = (add(i,10) for i in base) 16 # base = (add(i,10) for i in base) 17 for n in [1,10]: 18 base = (add(i,n) for i in base) 19 20 21 # 这里才开始展开生成器 22 # 第一个生成器展开 23 # base = (add(i,10) for i in base) 24 # base = (add(i,10) for i in range(4)) 25 # base = (10,11,12,13) 26 # 27 # 第二个生成器展开 28 # base = (add(i,10) for i in (10,11,12,13)) 29 # base = (20,21,22,23) 30 print(list(base)) # [20,21,22,23]
以上是关于迭代器与生成器的主要内容,如果未能解决你的问题,请参考以下文章