TTNTONZES

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

迭代与递归
迭代器协议:对象必须提供一个next方法 执行该方法要么返回迭代中下一项
要么引起一个stoplteration异常 以终止迭代
可迭代对象: 实现了迭代器协议的对象
协议是一种约定:可迭代对象实现了迭代器协议 Python的内部工具
(如for循环 sum max min函数等等)使用迭代器协议访问对象

for循环式中 调用了不可迭代对象内部的_iter_方法,把它们变成了可迭代

考虑序列型和非序列型 不可用列表下标 只可迭代器协议

啥是生成器:可以理解为一种数据类型 它自动实现了迭代器协议
故生成器就是可迭代对象
生成器在Python中表现:
1.生成器函数 常规函数定义 但是 使用yield语句而不是return返回结果
yield语句一次返回一个结果

def test():
    yield 1
    yield 2
    yield 3
g=test()
print(g)
print(g._nest_)
print(g._nest_)

 


2.生成器表达式 类似于列表推导 但是生成器返回按需产生结果的一个对象
而不是构建一个结果列表
生成器的优点:
对延迟操作提供了支持 不是立即产生结果 可在需要时产生

小结:
1,是可迭代对象
2、实现了延迟计算节省内存!

三元表达式

name='alex'
res='SB' if name=='alex' else ' 帅 哥'    
print(res)

 


列表解析

egg_list=[]
    for i in range(10)
    egg_list.append('鸡蛋%s' %i)
print(egg_list)
#or
[鸡蛋%s '%i for i in range(10)'] #二元
#or
[鸡蛋%s '%i for i in range(10)' if i >5]    #三元,没有四元

 



1.把列表解析的【】换成()得到的就是生成器表达式
2、列表解析与生成器都是一直能够便利的编程方式,只不过生成器
表达式更省内存
3、Python不但使用迭代器协议 让for循环更加通用,大部分函数
也是使用迭代器协议访问对象的

sum([i for i in range (10)])    #列表解析

sum=(i for i in range (10))    #生成器表达式 几乎不占用内存

def test():    #生成器函数
    yield 1
    yield 2
    yield 3
    yield 4
res=test()
print(res)
print(res._next_())
print(res._next_())
print(res._next_())

生成器的好处:
吃包子例子:
def product_baozi():
    ret[]
    for i in range(100)
        ret.append('包子%s'%i)
    return ret
boazi_list=product_baozi()
print(product)

#or
def product_baozi():
    for i in range(100)
        yield 'baozi%s'%i
pro_g=produce_baozi()

baozi1=pro_g._next_()
print('来一个人吃包子',baozi1)
baozi2=pro_g._next_()
print('来一个人吃包子',baozi2)
baozi3=pro_g._next_()
print('来一个人吃包子',baozi3)

#做一个返回值就输出 执行效率更好

def product_egg():
    ret[]
    for i in range(100)
        ret.append('鸡蛋%s'%i)
    return ret

 


#缺点1.占空间大 2.效率低

def product_egg():
    for i in range(100)
        yield '鸡蛋%s'%i
a=xiadan()
jidan=a._next_
print('XXX取鸡蛋',jidan)

 



生成器特性:
语法上类似函数:不同于 一次返回一个值
自动实现迭代器协议:
状态挂起:使用yield返回一个值 然后挂起函数状态 下次从离开的地方重新开始

优点:延迟计算 一次返回一个结果
提高代码可读性
注意事项:生成器只能遍历一次

生产者消费者模型:

#反例:
import time
def producer():
    ret=[]
    for i in range(100):
        time.sleep(0.1)
    ret.append('包子%s'%i)
    return ret

def consumer(res):
    for index,baozi in enumerate(res):
        time.sleep(0.1print('第%s个人,吃了%s'%(index,baozi))

res=producer()
consumer(res)

#yield相当于return控制函数返回值
#x=yield 另一个特性 接受send传过来的值 赋值给x

def test():
    print('开始啦')
    first=yield 
    print('第一次',first)
    yield 2
    print('第二次')
t=test()
res=t._next_()
print(res)
t._next_()
res=t.send('函数停留在first位置 我是给first赋值的')
print(res)


#正例;
def consumer(name):
    print('我是[%s],我准备开始吃包子了'%name)
    while True:
        baozi=yield
    print('%s 开心的吃掉了%s'%[name,baozi])
def producer():
    c1=consumer('aaa')
    c2=consumer('bbb_sb')
    c1.__next__()
    c2.__next__()
    for i in range(10):
        time.sleep(1)
        c1.send('韭菜馅包子%s',%i)
        c2.send('韭菜馅包子%s',%i)
producer()

 

posted on 2019-02-21 22:23  TTNTONZES  阅读(106)  评论(0编辑  收藏  举报