生成器是特殊的迭代器?

来源:互联网 发布:部队网络安全教育 编辑:程序博客网 时间:2024/05/26 05:52
生成器是特殊的迭代器,这可能是因为无论是迭代器,或者是生成器,都可以被for迭代,但是他们又不太像。
my_generator = (i for i in range(3))print(my_generator)for i in my_generator:   # generator也可以for调用    print(i)
结果
<generator object <genexpr> at 0x02C1EC00>012
像上面那样就构造生成器了,可以用for遍历,注:
list = [i for i in range(3)]
这样就是列表了
list1 = [1, 2, 3, 4]list1_iter = iter(list1)  # 获取迭代器print(list1_iter)for x in list1_iter:  # 也可以迭代数据    print(x)
结果:
<list_iterator object at 0x008D8950>1234
迭代器也可以被for迭代迭代器:一个对象,如果实现了__iter__和__next__,以为就是迭代器,像:
from collections import Iterableclass MyIter(object):    def __init__(self, *args):        self.mylist = args        self.current = 0    def __iter__(self):        return self    def __next__(self):        if self.current < len(self.mylist):            item = self.mylist[self.current]            self.current += 1            return item        else:            raise StopIterationif __name__ == '__main__':    myIter = MyIter(1, 2, 3, 4)    print(isinstance(myIter, Iterable))    for i in myIter:        print(i)
结果:
True1234
生成器:只要def中有yield关键字,就是一个生成器,(在这里把def说成函数不太舒服)。另外,还有例子一的产生生成器的方式。 yield生成器如:
def my_generator():    for index in [1, 2, 3]:        yield indext = my_generator()print(t)for i in t:    print(i)
结果
<generator object my_generator at 0x0364EC00>123
他们都可以被for遍历,因为for首先判断对象是否可以遍历,之后一直调用next(),直到捕获StopIteration的异常结束,而迭代器有__next__方法,而yield可以被next激活,如
import timei = [1, 2, 3, 4]i_iter = iter(i)   # 获取迭代器print(next(i_iter))print(next(i_iter))print(next(i_iter))print(next(i_iter))  time.sleep(1)print(next(i_iter))# 超出范围会抛出异常  StopIteration
结果
1234Traceback (most recent call last):  File "C:/Users/51613/Desktop/Myprogram/协程,迭代器生成器/用法iter()next().py", line 10, in <module>    print(next(i_iter))StopIteration
迭代器被next调用,超出范围抛StopIteration异常
import timedef gen():    i = 0    while i < 4:        yield i        i += 1g = gen()print(next(g))print(next(g))print(next(g))print(next(g))time.sleep(0.5)  # 让输出好看点print(next(g))
结果:
0123Traceback (most recent call last):  File "C:/Users/51613/Desktop/Myprogram/协程,迭代器生成器/next激活yield.py", line 16, in <module>    print(next(g))StopIteration
yield的作用:保存当前运行状态,然后暂停,即将生成器(函数)挂起;将yield关键字后面表达式的值作为返回值返回。生成器可以被next调用,yield被next激活,超出范围抛异常。除了next可以激活yield以外,send也可以:
import timedef send_yield():    i = 0    while i < 5:        temp = yield i        print(temp)        i += 1g = send_yield()print(g.send(None))  # send之前需要激活。用None激活,或者next()激活。print(g.send("luo"))print(g.send("luo"))print(g.send("luo"))print(g.send("luo"))time.sleep(1)print(g.send("luo"))
结果:
0luo1luo2luo3luo4luoTraceback (most recent call last):  File "C:/Users/51613/Desktop/Myfirstprogram/协程,迭代器生成器/send()唤醒生成器yield.py", line 19, in <module>    print(g.send("luo"))StopIteration
send可以激活yield,超出也会抛出异常,不同的是,他可以传参,并且这个参数可以在程序内接收。
原创粉丝点击