zoukankan      html  css  js  c++  java
  • day12

    生成器:就是自己用python代码写的迭代器,生成器的本质就是迭代器

    l1 = [1, 2, 3]
    iter1 = iter(l1)
    print(iter1)         #<list_iterator object at 0x00000247A62CDDD8>
    

    用以下方式构建一个生成器:

    1.通过生成器函数

    2.生成器表达式

    def func1(x):
        x += 1
        print(111)
        print(222)
        print(333)
        yield x
        x += 2
        print(666)
        yield 'ake'
        x += 3
        yield 4
        print(345)
    d = func1(5)          #生成器函数的对象
    # print(d)              #<generator object func1 at 0x0000021EF9F5E938>  生成器函数的地址
    print(d.__next__())    #111  222   333  6
    print(d.__next__())     #666   ake   因为yield没有返回x += 2 的值,所以打印的没有x
    print(d.__next__())     #ake  4
    print(d.__next__())     #打印出345,但是报错

    一个next 对应一个yield ,yield 将值返回给生成器对象。__next__()

    yield跟return的区别:

    return 结束函数,并将值返回给函数的执行者

    yield 不会结束函数,一个next 对应yield,给生成器对象.__next__()返回值

    生成器函数 vs 迭代器

    区别1:自定制的区别

    l1 = [1,2,3,4,5]
    l1.__iter__()             #迭代器
    
    
    
    def func1(x):             #生成器
        x += 1
        yield x
        x += 2
        yield x
        x += 3
        yield 4
    g1 = func1(5)
    print(g1.__next__())  #6
    print(g1.__next__())  #8
    print(g1.__next__())  #4

    区别2:内存级别的区别

    迭代器是需要可迭代对象进行转化,从本质就节省内存

    生成器直接创建,不需要转化,从本质就节省内存

    def func1():
        for i in range(1,10000):
            yield i
    g1 = func1()
    for i in range(50):
        print(g1.__next__())         #打印的是1-50
    for i in range(50):
        print(g1.__next__())         #打印的是51-100 

    每循环五十个,就打印五十个,非常节省内存

    send 与 next 的区别:

    def func1():
        count = yield 6   
        print(count)
        count1 = yield 7           
        print(count1)
        yield 8
    g = func1()
    #next(g)                  
    #g.send('ake')
    #next(g)
    print(next(g))         #这个next执行第一个yield 6
    print(g.send('ake'))  #send把值传给上一个yield,count = ‘ake’ 然后执行yield 7,count没有值,所以是None     
    print(next(g))      #这个next执行的是yield 8  

    send 与 next一样,也是对生成器取值(执行一个yield)方法

    send 可以给上一个yield传值

    第一个取值永远都是nex

    最后一个yield永远也得不到send传的值

    列表推导式:一行代码几乎搞定你需要的任何列表

    循环模式

    l =[i for i in range(1,20) ]
    print(l)

    筛选模式

    l3 = [i for i in range(1,15) if i % 3 == 0]
    print(l3)

    列表推导式优点:一行解决,方便

    缺点:不易排错,不能超过三次循环

    列表推导式不能解决所有列表的问题,所以不要太刻意用

    生成器表达式:只需要将列表推导式[]  换成()

    g = (i for i  in range(50))
    print(g.__next__())   #0
    print(g.__next__())   #1
    print(g.__next__())   #2

    一个next 打印一个

  • 相关阅读:
    tornado源码分析-多进程
    create a cocos2d-x-3.0 project in Xcode
    记录自己的傻逼的错误:找不到或无法载入主类
    MVC5 Entity Framework学习之实现主要的CRUD功能
    Linux中实现多网卡绑定总结
    it码农之心灵鸡汤(一)
    【高级算法】遗传算法解决3SAT问题(C++实现)
    MySQL-分区表-1
    OpenSift源代码编译过程记录
    Android Studio 视图解析
  • 原文地址:https://www.cnblogs.com/beriuta/p/9534070.html
Copyright © 2011-2022 走看看