迭代器与生成器

迭代器

什么是迭代?
个人认为迭代是将一个已知数据中的元素次第不断反馈的过程

什么是迭代器?

迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代
(只能往后走不能往前退)

什么是可迭代对象?
可迭代对象指的是内置有iter方法的对象,即obj.iter


'hello'.__iter__()
[1,2,3].__iter__()
{1,2,3}.__iter__()
{'qwe':123,'rt':1245}.__iter__()
open('123.txt','r').__iter__()
---------------------------------------------------------------------------

什么是迭代器对象?
可迭代对象执行obj.iter()得到的结果就是迭代器对象
而迭代器对象指的是即内置有iter又内置有next方法的对象

基于for循环,我们可以完全不再依赖索引去取值了
dic={‘a’:1,’b’:2,’c’:3}
for k in dic:
print(dic[k])
for循环的工作原理
1:执行in后对象的dic.iter()方法,得到一个迭代器对象iter_dic
2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3: 重复过程2,直到捕捉到异常StopIteration,结束循环

优点:
- 提供一种统一的、不依赖于索引的迭代方式
- 惰性计算,节省内存
缺点:
- 无法获取长度(只有在next完毕才知道到底有几个值)
- 一次性的,只能往后走,不能往前退

什么是生成器?
只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
通过next方法,的yield返回值,并且记录返回状态

def test():
    print('你好!')
    print ('你好!')
    print ('你好!')
    yield 'bob'
    yield 'jan'
    yield 'lucy'
a = test()
print(a.__next__())
print(a.__next__())   #本次打印从‘bob’之后
print(a.__next__())
你好!
你好!
你好!
bob
jan
lucy

列表解析

l1 = [i for i in range(10)]
print(l1)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
生成器表达式
l1 = (i for i in range(10))
print(next(l1))
print(next(l1))
print(next(l1))
print(next(l1))
print(next(l1))
0
1
2
3
4

生成器只能取只能取一次值


def test():
    for i in range(4):
        yield i

t = test()

t1 = (i for i in t)       #两个生成器
t2 = (i for i in t1)      #两个生成器
print(type(t1))
print(set(t1))
print(list(t2))            #生成器在产生时不会运行。通过next方法或遍历(for循环/list/set等)从中取值list方法从生成器中取值,t1和t2哪个先取走值,另一个则为空
print(list(t1))
<class 'generator'>
{0, 1, 2, 3}
[]
[]

练习

import time
def consumer(name):
    print('我是%s,我要开始吃包子了'%name)
    while 1:
        res = yield
        time.sleep (0.3)
        print('%s 很开心的把%s吃掉了'%(name,res))

def producer():
    c1 = consumer('jo')
    c2 = consumer('bob')
    c3 = consumer('lucy')
    c1.__next__()
    c2.__next__ ()
    c3.__next__ ()
    for i in range(10):
        time.sleep(0.3)
        c1.send('包子%d'%i)
        c2.send ('包子%d' % i)
        c3.send ('包子%d' % i)

producer()
我是jo,我要开始吃包子了
我是bob,我要开始吃包子了
我是lucy,我要开始吃包子了
jo 很开心的把包子0吃掉了
bob 很开心的把包子0吃掉了
lucy 很开心的把包子0吃掉了

猜你喜欢

转载自blog.csdn.net/marvin_wind/article/details/80110486