0403迭代器、生成器

一、迭代器

1,可以用for循环的就是迭代对象

内部含有__iter__方法的对象就叫做可迭代对象

可迭代对象就遵循可迭代协议。

可迭代对象:str,list,tuple,dict,set,range,
迭代器:f1文件句柄

 两种方式判断
print('__iter__' in dir(s))    #dir(),查看对象的所有方法


from collections import Iterable l = [1, 2, 3, 4] print(isinstance(l, Iterable)) # True
可迭代对象转化成迭代器:可迭代对象.__iter__()  --->迭代器
迭代器不仅含有__iter__,还含有__next__。遵循迭代器协议。
li=[1,2,3,4,5,6,]
li_obj=li.__iter__()   #迭代器

迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。
判断迭代器:

print('__iter__' in dir(l1_obj))
print('__next__' in dir(l1_obj))
from collections import Iterator
print(isinstance(l1_obj, Iterator))

迭代器的好处:
1,节省内存空间。
2,满足惰性机制。
3,不能反复取值,不可逆。

for循环,能遍历一个可迭代对象,他的内部到底进行了什么?

1,将可迭代对象转化成迭代器
2,内部使用__next__一个一个取值
3,运用了异常处理去处理报错。

用while循环实现for循环
li = [1,2,3,4,5,6,7] li_obj = li.__iter__() while True: try: i = li_obj.__next__() print()i

二、生成器

本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
生成器的产生方式:
1,生成器函数构造。
2,生成器推导式构造。
3,数据类型的转化。

第一:函数中只要有yield 那他就不是一个函数,而是一个生成器
第二:g称作生成器对象。
def func1():
    print(111)
    print(222)
    print(333)
    yield 666
    yield 555
    yield 777

g = func1()
print(g)  # <generator object func1 at 0x0000000001197888>

print(g.__next__())   #111  222  333  666
print(g.__next__())   #111 222 333 666  555
print(g.__next__())   #111 222 333 666   555  777
常规函数定义,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,
挂起函数的状态,以便下次重它离开的地方继续执行

def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield2

g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello')   #send的效果和next一样
print('***',ret)

#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
    # 第一次使用生成器的时候 是用next获取下一个值
    # 最后一个yield不能接受外部的值


posted @ 2018-04-03 19:20  Murray穆  阅读(133)  评论(0编辑  收藏  举报