• python(可迭代对象,迭代器,生成器及send方法详解)


    一.可迭代对象
    对象必须提供一个__iter__()方法,如果有,那么就是可迭代对象,
    像列表,元祖,字典等都是可迭代对象
    可使用isinstance(obj,Iterable)方法判断
    1 from collections import Iterable,Iterator
    2 l={'2':2,'fd':5,'f':6}
    3 l_i=l.__iter__()
    4 
    5 print(isinstance(l,Iterable))
    6 print(isinstance(l_i,Iterator))

    结果:

    True

    True

    二.迭代器

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

    from collections import Iterable,Iterator
    l={'2':2,'fd':5,'f':6}
    l_i=l.__iter__()
    s=isinstance(l,Iterable)
    print(s)
    print(isinstance(l_i,Iterator))
    打印结果:
    True
    True
    三.生成器
    遵循迭代器协议,相当于一种特殊的迭代器对象
    1.生成器表达式
    (1)三元表达式(必须是三元)
    name = '李'
    res='儿子' if name == '李' else '爸爸'
    print(res)
    打印结果:
    儿子
    (2)列表解析
    所谓列表解析就是列表内包含两元或三元表达式(不能是四元)
    1 l=['蚂蚁%s' %i for i in range(10)]
    2 l1=['蚂蚁%s' %i for i in range(10) if i >5]
    3 print(l)
    4 print(l1)
    打印结果:
    ['蚂蚁0', '蚂蚁1', '蚂蚁2', '蚂蚁3', '蚂蚁4', '蚂蚁5', '蚂蚁6', '蚂蚁7', '蚂蚁8', '蚂蚁9']
    ['蚂蚁6', '蚂蚁7', '蚂蚁8', '蚂蚁9']
    一行代码写出9*9乘法表:
    print(' '.join([' '.join(["%dX%d=%-2d" %(i,m,m*i) for i in range(1,m+1)]) for m in range(1,10)]))
    原理:.join()方法处理的结果是一个整体的字符串
    (3)生成器表达式
    1  l=['蚂蚁%s' %i for i in range(10)]#列表
    2  l=('蚂蚁%s' %i for i in range(10))#生成器表达式
    3  和列表相比不占用内存,使用一次生成一次
    4 l=('蚂蚁%s' %i for i in range(10))
    5 print(l)
    6 print(l.__next__())
    7 print(l.__next__())
    8 print(next(l))
    9 print(next(l))
    运行结果:
    <generator object <genexpr> at 0x000002191AFB5BA0>
    蚂蚁0
    蚂蚁1
    蚂蚁2
    蚂蚁3

    2.生成器函数
    优点:
    不会立即执行,节省内存。
    有需要时用一个现运行出一个,yield会保留当前状态,下次从当前位置继续运行,直到再次碰到yeild。
    对比两个过程理解:
    过程一(做出一个卖一个,即调用一次现运行出来一个结果)
    1 def product_baozi():
    2    for i in range(100):
    3       print('正在生产包子%s' %i)
    4       yield '一屉包子%s' %i #i=1
    5       print('开始卖包子')
    6 pro_g=product_baozi()
    7 baozi1=pro_g.__next__()
    运行结果:
    正在生产包子0
    过程二:(调用第二次,现运行出来第二个结果)
    1 def product_baozi():
    2    for i in range(100):
    3       print('正在生产包子%s' %i)
    4       yield '一屉包子%s' %i #i=1
    5       print('开始卖包子')
    6 pro_g=product_baozi()
    7 
    8 baozi1=pro_g.__next__()
    9 baozi1=pro_g.__next__()
    打印结果:
    正在生产包子0
    开始卖包子
    正在生产包子1
    3.生成器特性
    特性一:for循环可以遍历生成器
    def eges():
    for i in range(5):
    yield '鸡蛋%s' %i #i=1
    pro_g=eges()

    for i in pro_g:
    print(i)
    特性二:生成器只能迭代一次,用完就没了
    1 with open('人口普查','r',encoding='utf-8') as f:
    2     def g_population():
    3       for i in f:
    4          yield i
    5 
    6 
    7 print(sum(eval(l)['population']  for l in g_population()))
    8 print(g_population().__next__())  #此句会抛出异常
    4.利用生成器实现单线程并发
    send()方法,
    有一个参数,该参数指定的是上一次被挂起的yield语句的返回值,
    并且再次遇到yeild会向send传回一个值。
    实例:饭店吃饭
     1 import time
     2 def consetomer():
     3     print('服务员点餐')
     4     time.sleep(5)
     5     for i in range(5):
     6          cai=yield i   #接受send的传值,并向下执行,直到结束或遇到下一个yield(此时的yield会向send传回一个值)
     7          print('顾客开始吃第%s个菜' %cai)
     8 
     9 def canting():
    10     g1=consetomer()
    11     print(g1.__next__())
    12     print('厨师准备做菜')
    13     for i in range(1,5):
    14         time.sleep(1)
    15         print('第%s个菜做好了' %i)
    16         print('第%s个好吃' %g1.send(i)) #传送上一次挂起的yield并等待接受下一次yeild返回值
    17 canting()
    
    
    
     

    打印结果:

     1 服务员点餐
     2 0
     3 厨师准备做菜
     4 第1个菜做好了
     5 顾客开始吃第1个菜
     6 第1个好吃
     7 第2个菜做好了
     8 顾客开始吃第2个菜
     9 第2个好吃
    10 第3个菜做好了
    11 顾客开始吃第3个菜
    12 第3个好吃
    13 第4个菜做好了
    14 顾客开始吃第4个菜
    15 第4个好吃
     
    全面发展
  • 相关阅读:
    定义一个JobService,开启本地服务和远程服务
    提高Service优先级
    app中使用
    在java中
    每天学习点--------第六天(2017-10-10) 摘要: mysql和Oracle的区别
    每天学习点--------第五天(2017-10-9) 摘要: 常用的集合
    每天学习点--------第三天(2017-09-12)
    每天学习点--------第二天(2017-09-09)
    每天学习点--------第一天(2017-09-08)
    java开源安全框架-------Apache Shiro--第一天
  • 原文地址:https://www.cnblogs.com/snowony/p/11815779.html
Copyright © 2020-2023  润新知