• 生成器与推导式


     一,生成器

    生成器本质就是迭代器

    在python中有三种方式来获取生成器

      1.通过生成器函数

      2.通过各种推到式来实现生成器

      3.通过数据的转换也可以获取生成器

    def func():
     
        print(11)
        return 22
     
    ret = func()
    print(ret)
     
    # 运行结果:
    11
    22

     将函数中的return换成yield就是生成器

    #函数
    def func():
        print('这是函数func')
        return '函数func'
    func()
     
    # 生成器
    def func1():
        print('这是函数func1')
        yield '函数func' 
    func1()
    yield
    def func():
        print(1)
        # return 5
        yield 5
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    def func():                                       
        print(1)                                      
        yield 2                                       
        print(3)                                      
        yield 4                                       
    g=func()                                          
    print(g.__next__())                               
    print(g.__next__())                               
    # 1                                               
    # 2                                               
    # 3                                               
    # 4                                               
    print(g.__next__())        #报错    StopIteration   
    # def func():              
    #     print(1)             
    #     yield 2              
    #     # print(3)           
    #     # yield 4            
    # print(func().__next__()) 
    # print(func().__next__()) 
    # print(func().__next__()) 
    
    # 1   只是形成了一个生成器,一直在重复
    # 2   
    # 1   
    # 2   
    # 1   
    # 2   

    python2  next() iter()

    python3  next() __next__() iter()  __iter__()

    碰到return就结束函数

    碰到yield不结束就挂起

    生成器的好处,非常节省内存

    send
    def func():
        print(1)
        a = yield 2  # 1.挂起 2.返回值 3.接受值
        print(a)   # '123'
        print(3)
        b = yield 4
        print(b)   #'234'
    
    g = func()
    
    print(g.__next__())   #1 2  g.send(None)
    print(g.send('123'))  # send = next+传值
    # print(g.send('234'))  # send = next+传值
    
    # 1
    # 2
    # 123
    # 3
    # 4
    def func():
        print(1)
        a = yield 2  # 1.挂起 2.返回值 3.接受值
        print(a)   # '123'
        print(3)
        b = yield 4
        print(b)   #'234'
        c = yield 9
    
    g = func()
    
    print(g.__next__())   #1 2  g.send(None)
    print(g.send('123'))  # send = next+传值
    print(g.send('234'))  # send = next+传值  #多了一次迭代,应该再加一个yield
    
    
    

    第一次调用生成器的时候使用send里边的值必须是None

    yield from

    def func():
        lst = ['卫龙','老冰棍','北冰洋','牛羊配']
        yield from lst
    g = func()
    for i in g:
        print(i)
    def func():
        li = [1,2,3,4]
        # yield li
        yield from li
    
    ret = func()  # 把生成器的地址给了ret
    print(ret.__next__())       #1
    # # 执行ret这个变量的指向的生成器地址
    print(ret)                  #<generator object func at 0x000001B3B3EA97D8>
    # # 在全局空间找到一个变量叫做ret的,打印它的值 值就是生成器的地址
    def func():
        li = [1,2,3,4]
        l2 = [5,6,7,8]
        yield from li
        yield from l2
    ret = func()  # 把生成器的地址给了ret
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    def func():
        li = [1,2,3,4]
        l2 = [5,6,7,8]
        # yield from li
        # yield from l2
        for i in li:
            yield i
    
        for em in l2:
            yield em
    #
    ret = func()  # 把生成器的地址给了ret
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())

    总结

    1.生成器的本质就是一个迭代器

    2.生成器一定是一个迭代器,迭代器不一定是一个生成器

    3.生成器是可以让程序员自己定义的一个迭代器

    4.生成器的好处,节省内存空间

    5.生成器的特性 一次性的,惰性机制,从上向下

    6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None)

     值必须是None,一般我建议你们使用__next__

    7. python2 iter()  next()

    python3 iter()  next()  __next__() __iter__()

    8.yield from 将可迭代对象元素逐个返回

     二,推导式

    1.列表推导式

    li = []
    for i in range(10):
        li.append(i)
    print(li)         #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    print([i for i in range(10)])
     #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    li = []
    for i in range(10):
        if i%2 == 1:
            li.append(i)
    print(li)    #[1, 3, 5, 7, 9]
    print([i for i in range(10) if i%2 == 0])  # 过滤(筛选)
    #[0, 2, 4, 6, 8]
    #for 循环的嵌套
    li = []
    for i in range(10):
        for em in range(3):
            li.append(em)
    print(li) 
    #[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
    print([j for i in range(10) for em in range(3) for j in range(5)])

    2.集合推导式

    s = {i for i in range(10)}
    print(s)      #{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    3.字典推导式

    print({i:i+1 for i in range(10)})   
    #{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}

    4.没有元组推导式    其实是一个生成器推导式

    g = (i for i in range(10))
    print(g)    #<generator object <genexpr> at 0x000001D7DD1497D8>

     总结

    1.外部需要容器包一下,  里边第一个位置 结果 剩下位置都是语句

    2.推导式 -- 面试  实现小的需求时可以使用推导式,推导式节省代码

    3.推导式不要写太长,可读性查.

  • 相关阅读:
    javascript游戏引擎
    BI 可视化
    nodeJS 相关开源项目
    bean validation 技术规范
    JForum 源码分析
    lemon OA 我长时间经历的第一个开源项目
    Rete算法
    摘自知乎--mysql
    copy and paste ,做到这样也很牛逼了
    servlet 3.0特性说明
  • 原文地址:https://www.cnblogs.com/Xiao_Xu/p/10542785.html
Copyright © 2020-2023  润新知