函數【五】生成器/推導式

py_生成器、列表推導式

 

1、生成器

一、什麼是生成器?html

  能夠理解爲一種數據類型,這種數據類型自動實現了迭代器協議(其餘數據類型須要調用本身內置的__iter__方法),因此生成器就是可迭代對象;python

二、生成器在python中的表現形式?程序員

  • 生成器函數:常規函數定義,可是使用yield語句而不是使用retum語句返回結果,yield語句一次返回一個結果,在每一個結果中間掛機函數的狀態,以便下次從他離開的地方執行;
  • 生成器表達式:相似於列表推導,可是生成器返回按須要產生結果的一個對象,而不是一次構建一個列表
    #生成器函數(只要函數內部包含有yield關鍵字,那麼函數名()的到的結果就是生成器,而且不會執行函數內部代碼)
    cp = [1,2,3,4,5]
    def test():
        yield 1
        yield 2
        yield 3
    date = test()
    print(next(date))
    print(next(date))
    print(next(date))
    
    生成器函數
    生成器函數
    #三元表達式
    name = "lw"
    res = "sb" if name == "lw" else "帥哥"
    print(res)
    
    egg1 = ["雞蛋 %s" %i for i in range(10) if i > 5 ]
    print(egg1)
    
    #正常列表(在內存中存儲)
    egg_list = []
    for i in range(10):
        egg_list.append("雞蛋 %s" %i)
    print(egg_list)
    
    #列表解析(在內存中存儲)
    egg = ["雞蛋 %s" %i for i in range(10)]
    print(egg)
    
    #生成器表達式(基於迭代器協議轉換成可迭代對象,不佔內存)
    laomuji = ("雞蛋 %s" %i for i in range(10))
    print(laomuji)   #<generator object <genexpr> at 0x000001A6F46231A8>
    print(laomuji.__next__()) #等於next(laomuji)
    
    生成器表達式

    三、生成器取值的幾種方式app

    • 直接調用生成器內置的__next__方法;生成器內的數據取完,在取會拋出StopIteration
      def func():
          print(1)
          yield 5    # 個人函數走到這了
          print(2)
          yield 9    # 個人函數走到這了
      
      g = func()   # 生成一個生成器
      
      print(g.__next__())
      print(g.__next__())  # 每次取值會從上一個yield開始
      print(g.__next__())  # 生成器內的數據取完,在取會拋出StopIteration
      
      next方法
      next方法
      • 生成器調用send()方法,send()至關於(next + 傳值),傳值給yield,第一次調用生成器的時候使用send裏邊的值必須是None
        def func():
            print(1)
            a = yield 2    # 1.掛起 2.返回值 3.接受值
            print(a)
            print(3)
            b = yield 4
            print(b)
            c = yield 9
        g = func()  # 生成一個生成器
        print(g.__next__())
        print(g.send('123'))
        print(g.send('234'))
        #第一次調用生成器的時候使用send裏邊的值必須是None
        
        send方法

         四、簡述yield與yield from的區別ide

        def generator():
            for i in range(5):
                yield i
        t = generator()
        print(t.__next__())
        
        def generator_1():
            yield 1
            yield 2
            yield 3
            yield 4
            yield 5
        t1 = generator_1()
        print(t1.__next__())
        
        上面這兩種方式是徹底等價的,只不過前者更簡單一些。
        
        yield
        yield
        def generator1():
            item = range(10)
            for i in item:
                yield i
        
        def generator2():
            yield ‘a‘
            yield ‘b‘
            yield ‘c‘
            yield from generator1() #yield from iterable本質上等於 for item in iterable: yield item的縮寫版
            yield from [11,22,33,44]
            yield from (12,23,34)
            yield from range(3)
        
        for i in generator2() :
            print(i)
        
        
        從上面的代碼能夠看書,yield from 後面能夠跟的式子有「 生成器  元組 列表等可迭代對象以及range()函數產生的序列」
        
        yield from
        yield from
        def test():
            for i in range(10):
                yield i
        a = test()
        print(a.__next__())
        for j in a:
            print(j)
        
        def test():
            yield from range(10)
        b = test()
        print(b.__next__())
        for j in b:
            print(j)

         

        2、推導式

        # 推導式:
        # 1.列表
        # 2.集合
        # 3.字典
        # 4.生成器表達式(只要是小括號的就是生成器表達式)
        li = []
        for i in range(10):
            li.append(i)
        print(li)
        
        print([i for i in range(10)])
        [結果 語法] #容器
        
        li = []
        for i in range(10):
            if i%2 == 1:
                li.append(i)
        print(li)
        
        print([i for i in range(10) if i%2 == 0])  # 過濾(篩選)
        
        li = []
        for i in range(10):
            for em in range(3):
                li.append(em)
        print(li)
        
        print([j for i in range(10) for em in range(3) for j in range(5)])
        
        集合推導式
        s = {i for i in range(10)}
        print(s)
        
        字典推導式
        print({i:i+1 for i in range(10)})
        
        生成器表達式
        g = (i for i in range(10))

        總結:函數

            #     1.生成器的本質就是一個迭代器    #     2.生成器必定是一個迭代器,迭代器不必定是一個生成器    #     3.生成器是可讓程序員本身定義的一個迭代器    #     4.生成器的好處,節省內存空間    #     5.生成器的特性 一次性的,惰性機制,從上向下    #     6.send至關於 next+傳值,第一次觸生成器的時候,若是使用send(None)值必須是None,通常我建議大家使用__next__    #     7.    python2 iter()  next()    #            python3 iter()  next()  __next__() __iter__()    #     8.yield from 將可迭代對象元素逐個返回
相關文章
相關標籤/搜索