未加星标

迭代器与生成器

字体大小 | |
[开发(python) 所属分类 开发(python) | 发布者 店小二05 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏
迭代器 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]

本文开发(python)相关术语:python基础教程 python多线程 web开发工程师 软件开发工程师 软件开发流程

分页:12
转载请注明
本文标题:迭代器与生成器
本站链接:http://www.codesec.net/view/561311.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(python) | 评论(0) | 阅读(10)