1. 程式人生 > >python生成器初步瞭解

python生成器初步瞭解

一.生成器

  生成器的本質就是迭代器     一個一個的建立物件     

  1.建立生成器的方式:

    1.生成器函式

    2.通過生成器表示式來獲取生成器

    3.型別轉換

  2.優點

    節省記憶體 ,生成器本身就是程式碼,巨虎不佔用記憶體

  3.特點

    惰性機制,只能向前,不能反覆

二.生成器函式

  函式中包含了yield   這個函式就是生成器函式

def func():
    print("你叫xxx?")
    yield "alex"
    print("真的?")
    yield "真的"
    print("Are you sure?")
    yield "那叫我屌絲把"
ret = func()      # 拿到的是ret生成器 只是產生一個生成器並不是執行
print(ret)         # 只能是列印 生成器的地址

print(ret.__next__())    # 生成器就是迭代器,用next一個一個拿
print(ret.__next__())
print(ret.__next__())
print(ret.__next__())   # 沒有下一個了就會出現  StopIteration  錯誤

  1.yield 

    1.yield和return差不多 yield是分段執行一個函式

             return是立即結束這個函式的執行

    2.生成器在執行的時候返回生成器,而不是執行執行此函式 

  2.能向下執行的兩個條件

    1.__next__ 執行到下一個yield

    2.send() 執行到下一個yield,給上一個yield位置傳值.在第一次執行生成器的時候不能用send(),最後一個yield也不會傳值

   

def fn():
    print("韭菜盒子")
    a = yield "西紅柿炒番茄"
    print("a",a)
    b = yield "西紅柿炒雞蛋"
    print("b",b)
    c = yield "番茄炒雞蛋"
    print("c",c)
    yield "火燒"

gen = fn()
# send()可以給上一個yield位置傳參
print(gen.__next__())
print(gen.send("番茄"))
print(gen.send("西紅柿"))
print(gen.send("雞蛋"))

  3.獲取生成器資料

    1.所有生成器都是迭代器都可以使用for迴圈

    2.都可以使用list()函式來獲取生成器內所有的資料  

  4.生成器的記錄

    生成器中記錄的是程式碼而不是函式的執行

    當執行到__next__()  執行此空間中的程式碼,執行到yield結束

def func():
    print("我的天哪 ")
    yield "寶寶"
gen = func() # 建立生成器.  此時執行會把生成器函式中的程式碼記錄在記憶體

三.推導式

  1.列表推導式            [結果             for迴圈    if]

lst = [ i**2 for i in range(1,101) if i % 2 == 0]
print(lst)

  

  2.字典推導式    {結果(k,v)      for迴圈         if}

#尋找名字中帶有兩個e的⼈的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
        ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]

lst = [ el for name in names for el in name if el.count("e") == 2  ]
print(lst)

  

  3.集合推導式    {結果(k)         for迴圈         if}

四.生成器表示式    

  (結果          for迴圈           if)

g = (i for i in range(10))    #一次性生成器表示式

print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())    # 用完就沒了   想再次用必須再寫一次表示式

五.yield from

def func():
    lst = ["衣服%s" %i for i in range(500)]
    yield  from lst # 可以把一個可迭代物件分別進行yield返回

    lst1 = ["python%s期" %i for i in range(1,19)]
    yield from lst1    #  只有上面的yield next完才能輪到第二個
g = func()
print(g.__next__())
print(g.__next__())