日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

《Python》 生成器和列表推导式

發布時間:2023/12/13 综合教程 24 生活家
生活随笔 收集整理的這篇文章主要介紹了 《Python》 生成器和列表推导式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、初識生成器:

    生成器就是自己用Python代碼寫的迭代器,生成器的本質就是迭代器。

    1、Python中提供的生成器:

      1、生成器函數:

        使用yield語句而不是return語句返回結果。yield語句一次返回一個結果,在每個結果中間,掛起函數的狀態,以便下次從它離開的地方繼續執行。

      2、生成器表達式:

        類似于列表推導,但是,生成器返回按需產生結果的一個對象,而不是一次構建一個結果列表。

    2、生成器Generator:

      本質:迭代器(所以自帶了__iter__方法和__next__方法,不需要我們去實現)

      熱點:惰性運算,開發者自定義

二、生成器函數:

    一個包含yield關鍵字的函數就是一個生成器函數。yield可以為我們從函數中返回值,但是yield又不同于return。

    yield和return的區別:

      return:結束函數,給函數的執行者返回值。

      yield:不會結束函數,一個next對應一個yield,給 生成器對象.__next__() 返回值

    生成器函數vs迭代器:

      1.自定制取值:

 1 只能一個一個取值:
 2 l1 = [1,2,3,4,5]
 3 l1.__iter__()
 4 
 5 可以自定義取值:
 6 def func1(x):
 7     x += 1
 8     yield x
 9     x += 3
10     yield x
11     x += 5
12     yield x
13 g1 = func1(5)
14 print(g1.__next__())
15 print(g1.__next__())
16 print(g1.__next__())

自定制的區別

      2、內存級別的區別:

        迭代器是需要可迭代對象進行轉換,可迭代對象非常占內存。

        生成器直接創建,不需要轉化,從本質就節省內存。

def func1():
    for i in range(1000000):
        yield i
g1 = func1()
for i in range(50):
    print(g1.__next__())

生成器按需取值

 1 import time
 2 def genrator_fun1():
 3     a = 1
 4     print('現在定義了a變量')
 5     yield a
 6     b = 2
 7     print('現在又定義了b變量')
 8     yield b
 9 
10 g1 = genrator_fun1()
11 print('g1 : ',g1)       #打印g1可以發現g1就是一個生成器
12 print('-'*20)   #我是華麗的分割線
13 print(next(g1))
14 time.sleep(1)   #sleep一秒看清執行過程
15 print(next(g1))
16 
17 初識生成器函數

初始生成器函數

生成器有什么好處呢?就是不會一下子在內存中生成太多數據

假如我想讓工廠給學生做校服,生產2000000件衣服,我和工廠一說,工廠應該是先答應下來,然后再去生產,我可以一件一件的要,也可以根據學生一批一批的找工廠拿。
而不能是一說要生產2000000件衣服,工廠就先去做生產2000000件衣服,等回來做好了,學生都畢業了。。。

def produce():
    """生產衣服"""
    for i in range(2000000):
        yield "生產了第%s件衣服"%i

product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服
num = 0
for i in product_g:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

生成器按需取值

三、send

   send和next一樣,也是對生成器取值(執行一個yield)的方法。

   send可以給上一個yield傳值。

   第一次取值永遠都是next。

   最后一個yield永遠也得不到send傳的值。

def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield2

g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello')   #send的效果和next一樣
print('***',ret)

send的用法

四、列表推導式和生成器表達式   

    1.把列表解析的[]換成()得到的就是生成器表達式

    2.列表解析與生成器表達式都是一種便利的編程方式,只不過生成器表達式更節省內存

    3.Python不但使用迭代器協議,讓for循環變得更加通用。大部分內置函數,也是使用迭代器協議訪問對象的。

    一、列表推導式:一行代碼幾乎搞定你需要的任何的列表

        優點:一行解決,方便。

        缺點:容易著迷,不易排錯,不能超過三次循環。

           列表推導式不能解決所有列表的問題,所以不要太刻意用。

      1、循環模式:[ 變量(加工后的變量) for 變量 in 可迭代對象 ]

        prite([ i for i in range(1,101)]) # 循環打印1~100

        prite([ ‘Python第%s期’ % i for i in range(1,16)])

      2、篩選模式:[ 變量(加工后的變量)for 變量 in 可迭代對象 if 條件 ]

        prite([ i for i in range(1,31) if i % 3 == 0 ]) #打印30以內能被3整除的數

        prite([ i ** 2 for i in range(1,31) if i % 3 == 0 ]) #打印30以內能被3整除的數的平方

names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]

print([name for lst in names for name in lst if name.count('e') >= 2])  # 注意遍歷順序,這是實現的關鍵

找到嵌套列表中名字含有兩個‘e’的所有名字     

    二、字典推導式:      

mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)

將一個字典的key和value對調

mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()}
print(mcase_frequency)

合并大小寫對應的value值,將k統一成小寫

    三、集合推導式:

squared = {x**2 for x in [1, -1, 2]}
print(squared)
# Output: set([1, 4])

計算列表中每個值的平方,自帶去重功能

總結

以上是生活随笔為你收集整理的《Python》 生成器和列表推导式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。