生成器是特殊的迭代器?

生成器是特殊的迭代器,这可能是因为无论是迭代器,或者是生成器,都可以被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>
0
1
2
像上面那样就构造生成器了,可以用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>
1
2
3
4
迭代器也可以被for迭代

迭代器:一个对象,如果实现了__iter__和__next__,以为就是迭代器,像:
from collections import Iterable


class 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 StopIteration

if __name__ == '__main__':
    myIter = MyIter(1, 2, 3, 4)
    print(isinstance(myIter, Iterable))
    for i in myIter:
        print(i)
结果:
True
1
2
3
4
生成器:只要def中有yield关键字,就是一个生成器,(在这里把def说成函数不太舒服)。另外,还有例子一的产生生成器的方式。
 yield生成器如:
def my_generator():
    for index in [1, 2, 3]:
        yield index

t = my_generator()
print(t)
for i in t:
    print(i)
结果
<generator object my_generator at 0x0364EC00>
1
2
3
他们都可以被for遍历,因为for首先判断对象是否可以遍历,之后一直调用next(),直到捕获StopIteration的异常结束,而迭代器有__next__方法,而yield可以被next激活,如
import time

i = [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
结果
1
2
3
4
Traceback (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 time


def gen():
    i = 0
    while i < 4:
        yield i
        i += 1

g = gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
time.sleep(0.5)  # 让输出好看点
print(next(g))
结果:
0
1
2
3
Traceback (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 time


def send_yield():

    i = 0
    while i < 5:
        temp = yield i
        print(temp)
        i += 1

g = 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"))
结果:
0
luo
1
luo
2
luo
3
luo
4
luo
Traceback (most recent call last):
  File "C:/Users/51613/Desktop/Myfirstprogram/协程,迭代器生成器/send()唤醒生成器yield.py", line 19, in <module>
    print(g.send("luo"))
StopIteration
send可以激活yield,超出也会抛出异常,不同的是,他可以传参,并且这个参数可以在程序内接收。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值