Python迭代器、生成器

  python中经常用到迭代,但是对于迭代器、生成器一直处于模糊的理解,查看了不少资料,感觉有些清晰了。

  什么是迭代

  通过for循环不断的拿到list中的值就是迭代,迭代就是循环做重复的事情。

for i in range(10):
    print(i)

   可以通过for循环进行迭代的对象称为可迭代对象(Iterable),如何判断是否是可迭代对象,可以用collection模块中的Iterable来判断

>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance("",Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance(123,Iterable)
False
>>> isinstance((),Iterable)
True

   可迭代对象内部都实现了_iter_方法,例如list,通过help(list)查看

|  __iter__(self, /)
|      Implement iter(self).

  可迭代对象可以通过循环拿到值,但是可迭代对象不是迭代器。

  迭代器

  为什么list、dict、str等数据类型不是Iterator?这是因为Python的迭代器(Iterator)对象表示的是一个数据流,迭代器(Iterator)对象可以被next() 函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

      迭代器(Iterator)甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
  迭代器可以通过next函数不断计算下一个数据。

>>> c=iter(b)
>>> c
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator
>>> next(c)
0

   可以看到list是可迭代对象,但是无法使用next函数,因为它不是迭代器,而c则可以

  创建迭代器的方法

  可以通过 iter(list/set..) 来把一个可迭代对象创建为迭代器。

  生成器

  生成器可以理解为特殊的迭代器,它也实现了iter和next方法,也是基于计算的迭代,一边计算一边迭代的机制称为generator

  创建生成器的方法

  1. 通过列表推导式,把列表生成式的[]改为()

>>> g=(x for x in range(10))
>>> type(g)
<class 'generator'>

   2.通过生成器函数得到一个生成器,定义一个包含yield的函数,普通函数中通过return返回值,返回后整个函数已经结束,而生成器函数中通过yield返回值,返回后会记录yield的位置,然后下次再调用会从yield的位置继续执行

def func(n):
    a=1
    for i in range(n):
        yield a
        a+=i

a=func(5)
print(a)
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())

   看下结果,返回的是一个生成器,可以通过next函数不断拿到值,直到抛出StopIteration

 

 

 

  总结:

1. 可迭代对象不一定是迭代器

2.迭代器一定是可迭代对象

3.实现了__next__函数(或可以通过next函数取值),__iter__函数的是迭代器

4.生成器是特殊的迭代器,可以通过列表推导式或者函数中使用yield来获得生成器

 

posted @ 2019-11-21 16:34  不当咸鱼  阅读(173)  评论(0编辑  收藏  举报