Python拾遗之迭代器和生成器(二)

迭代器与生成器(二)


关于生成器(在Python中)

生成器可以称为特殊的迭代器,因为它具有可迭代的属性,也具备next方法,而它的特殊之处在于其具有协同程序的概念,从语法上讲,生成器是一个带yield语句的函数,从而保证生成器能暂停执行,返回中间的结果(这也是yield语句的功能,即返回一个只给调用者并暂停执行),当生成器的next方法被再次调用时,它会准确的从离开的地方继续执行。例如,通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含特别多元素的列表,不仅占用很大的存储空间,而且如果仅仅需要访问几个元素,那绝大多数元素占用的空间都浪费了。但是,如果列表元素可以按照某种算法推算出来,在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。据上述,这种一边循环一边计算的机制,并且具有上所述的挂起返回中间值并且多次继续的协同程序,谓之生成器(Generator)


关于协同程序

可以运行的独立函数调用,可以暂停或者挂起,同时保存现场,并从程序离开的地方重新开始。依靠挂起,完成cpu或者IO的切换,达到协程的意义。


构建生成器对象:

实例一:(调用生成器函数,获得一个生成器对象)

def simple_gen():
        yield 1
        yield 2
gen_obj = simple_gen()
print type(gen_obj)

运行结果:

<type 'generator'>

实例二:(把一个列表生成式的[]改成(),就创建了一个generator)

li = [i * i for i in range(10)]
print type(li)
gen = (i * i for i in range(10))
print type(gen)

运行结果:

<type 'list'>
<type 'generator'>

如何使用生成器

实例三:(手动迭代,当生成器对象无值返回时,一个StopIteration将会抛出)


>>> gen = (i * i for i in range(3))
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
4
>>> gen.next()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
StopIteration

实例四:(python的for循环有next()调用和对StopIteration的处理)

gen = (i * i for i in range(3))
for i in gen:
    print i

运行结果:

0
1
4

实例五:(利用send方法将值送给生成器,调用close方法,让生成器抛出异常)


>>> def sum(start=0):
    num = start
while True:
#保证send()回来的数据值得到接收
        var = (yield num)
        if var is not None:
            num = var
        else:
            num += 1
>>> t = sum(2)
>>> t.next()
2
>>> t.next()
3
>>> t.next()
4
>>> t.send(7)
7
>>> t.send(9)
9
>>> 
>>> t.close()
>>> t.next()

实例六:(throw方法允许客户传入要抛出的任何类型的异常)

>>> def sum(start=0):
    num = start
    while True:
        var = (yield num)
        if var is not None:
            num = var
        else:
            num += 1
>>> s = sum(1)
>>> s.next()
1
>>> s.next()
2
>>> s.throw(ValueError('Memada!!!'))   
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 4, in sum
ValueError: Memada!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JaysenLeo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值