python之迭代器与生成器

  一、什么是迭代器

  要说迭代器首先我们要先知道什么是迭代,迭代在计算机中是一种算法指的是让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。在python中迭代一般用于从一个数据对象中不断的取值,这种可以不断取值的属性就叫做iterable可迭代的,如何判断一个数据对象是否是可迭代的,只需要判断其是否含有内置函数__iter__,因为所有可迭代的对象都遵循可迭代协议即都含有__iter__方法。那么知道了迭代是什么,迭代器又是什么呢?迭代器是对可迭代对象取值优化的一种数据类型,它不像列表、元祖等可迭代对象是将所有元素全部存储在内存中,它是在被调用时才读取一个值到内存中,且迭代器只能从头到尾一个一个取值。

 

  二、如何判断迭代器

  判断一个对象是否是迭代器有以下两种方法:

  1、'__iter__' in object and '__next__' in object

   判断该对象中是否包含__iter__和__next__这两个方法,因为所有迭代器都遵循迭代器协议即每个迭代器中都包含__iter__、__next__两个方法

  2、from collections import Iterator

  print(isinstance(object,Iterator))

  利用Iterator模块判断对象是否是迭代器,如果输出True则表示该对象是迭代器,输出False则表示该对象不是迭代器

 

 三、获取迭代器

  迭代器一般都是python内部使用的,我们如何获得一个迭代器对象呢?如果我们想要获取一个迭代器对象可以使用内置函数iter(),它可以把所有可迭代对象转成迭代器,另外map函数、filter函数也可以获得迭代器对象,打开文件获得的文件句柄也是一个迭代器对象

 

 四、什么是生成器

  生成器就是python提供的可以让程序员编写的迭代器,它具有迭代器的所有特性和内置函数

 

 五、获取生成器

 1、生成器函数

  生成器函数的定义其实大部分和普通函数一样,只是生成器函数用yield代替了return来返回值,一个生成器函数的例子如下

  

 1 def aver():
 2     total=0
 3     day=0
 4     avg=0
 5     while True:
 6         day_num=yield  avg
 7         total+=day_num
 8         day+=1
 9         avg=total/day
10 g=aver()
11 print(next(g))
12 print(g.send(10))
13 --------------------------------------------------------------------------------------
14 0
15 10.0
View Code

 生成器函数在被调用时只是返回给你一个生成器对象,并不会执行函数体中的代码,只有当你第一次使用next函数去取它的返回值时才开始执行函数体中的代码,然后当遇到yield时将返回值返回并将函数停止在那一步,这是可以使用send函数给yield传值,然后yield接收之后会继续执行之后的代码,此时生成器函数中需要有两个yield。值得注意的是生成器函数中不像普通函数一样,普通函数只能有一个return,但是生成器函数中可以有多个yield,并且多个yield是顺序执行的

 

  2、生成器表达式

  生成器表达式和列表推导式(列表解析)是类似的,只需要将列表推导式外面的[]中括号替换为()小括号即可。

  

 1 #列表推导式范例
 2 l=[i for i in range(10)]
 3 print(l)
 4 --------------------------------------------------------------------------------------
 5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 6 
 7 
 8 #列表生成式
 9 l=(i for i in range(10))
10 print(l)
11 --------------------------------------------------------------------------------------
12 <generator object <genexpr> at 0x034657E0>
View Code

 

 六、yield from

 yield from是在python3中新加的语法,只是在生成器函数中简化循环的一种用法

 

 七、生成器进阶示例

  

 1 def demo():
 2     for i in range(4):
 3         yield i
 4 
 5 g=demo()
 6 
 7 g1=(i for i in g)
 8 g2=(i for i in g1)
 9 
10 print(list(g1))
11 print(list(g2))   #生成器g中的值在上一次g1中被取完,所以g2取值时g中已经没有值
12 --------------------------------------------------------------------------------------
13 [0, 1, 2, 3]
14 []
View Code
 1 def add(n,i):
 2     return n+i
 3 def test():
 4     for i in range(4):
 5         yield i
 6 g=test()
 7 for n in [1,10]:  #整个for循环中生成器表达式g都没有取值,同时生成器表达式中的g被替换为test()
 8     g=(add(n,i) for i in g) 
 9 print(list(g)) # =》(add(n,i) for i in (add(n,i) for i in g) ),n=10
10 --------------------------------------------------------------------------------------
11 [20,21,22,23]
View Code

 

 

 1 #普通的for循环
 2 def f():
 3     for i in range(10):
 4         yield i
 5 g=f()
 6 print(next(g))
 7 print(next(g))
 8 --------------------------------------------------------------------------------------
 9 0
10 1
11 
12 
13 #yield from简化的循环
14 def f():
15     yield from range(10)
16 g=f()
17 print(next(g))
18 print(next(g))
19 --------------------------------------------------------------------------------------
20 0
21 1
View Code

 

posted @ 2017-08-02 16:01  魅力宁波  阅读(152)  评论(0)    收藏  举报