Python--生成器

来源:https://www.cnblogs.com/sunnytomorrow/archive/2020/06/09/13081734.html
-Advertisement-
Play Games

學習生成器之前,首先需要認識列表生成式,直奔主題。 1、簡單列表生成式示例: 1 b = [ i for i in range(10)] 2 print(b) 3 4 >>> 5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 看樣子好像很NB的樣子,其實它等價於: 1 c = [] ...


學習生成器之前,首先需要認識列表生成式,直奔主題。

1、簡單列表生成式示例:

1 b = [ i for i in range(10)]
2 print(b)
3 
4 >>>
5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

看樣子好像很NB的樣子,其實它等價於:

1 c = []
2 for i in range(10):
3     c.append(i)
4 print(c)
5 
6 >>>
7 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

其實還是有點NB的,畢竟代碼少了,手動嘻嘻嘻!

2、削微高級點的列表生成式:

1 def func(x):
2     a = x + 1
3     b = a + x
4     return b
5 d = [ func(i) for i in range(10) ]
6 print(d)
7 
8 >>>
9 [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

生成式生成的數據可以交給函數處理,進而得到預定規則的一組數據。

下麵有請主角登場!!!!

生成器:在Python中,一邊迴圈一邊計算的機制,稱為生成器:generator。

  我們知道了,通過列表生成式,我們可以直接創建一個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。

創建生成器的姿勢:將生成式的"[]"換成"()"就ok了,是不是超級簡單。。。

 1 a = ( i for i in range(10))
 2 print(a)
 3 for i in a:
 4     print(i)
 5 
 6 >>>
 7 <generator object <genexpr> at 0x00000270A14EB0B0>
 8 0
 9 1
10 ..
11 9

由上面的例子可見,列印的a已不是一個列表,而是a的記憶體地址。而且a可以通過for迴圈將其中的值取出。

就用一個小慄子完成生成式和生成器比較吧:

1 # 生成b需要很長時間
2 b = [ i for i in range(100000000) ]
3 # 生成c很快,因為不需要實際寫數據,c的數據是在使用時才生成
4 c = ( i for i in range(100) )

生成器特性:

1.生成器只能一個個的取數據
2.生成器只有在調用時才會生成相應的數據
3.生成器只記住當前位置的地址,之前的的記憶體地址都沒了
4.只有一個__next__()方法
5.生成器不能根據索引位置取值
1 c = ( i for i in range(100) )
2 print(c.__next__())
3 print(c.__next__())
4 print(c[0])
5 
6 >>>
7 0
8 1
9 TypeError: 'generator' object is not subscriptable

#############################################################

示例:瞭解斐波那契數列(下個數為前兩個數的和)

 1 def fib(max):
 2     n, a, b = 0, 0, 1
 3     while n < max:
 4         print(b)
 5         a, b = b, a+b  #註意a, b = b, a+b 等價於 t(b,a+b);a=t[0];b=t[1],而不是 a=b;b=a+b
 6         n = n + 1
 7     return "done"
 8 fib(7)
 9 >>>
10 1
11 1
12 2
13 3
14 5
15 8
16 13

使斐波那契數列變成一個生成器

 1 def fib(max):
 2     n, a, b = 0, 0, 1
 3     while n < max:
 4         yield b  #yield返回當前狀態的值,程式停在此處
 5         a, b = b, a+b
 6         n = n + 1
 7     return "---done---" 
 8 # fib(5)  #此時執行,並無返回值,因為沒有取值。使用__next__()進行取值
 9 f = fib(5)
10 print(f.__next__())
11 print(f.__next__())
12 print(f.__next__())
13 print(f.__next__())
14 print(f.__next__())
15 print(f.__next__())
16 
17 >>>
18 1
19 1
20 2
21 3
22 5
23 StopIteration: ---done---  # 當超出時報錯
使用yield後,可以使用__next__()方法,中斷函數的執行,在中斷之後可以執行其他的操作,然後還可以通過__next__()再進入
例如:
 1 def fib(max):
 2     n, a, b = 0, 0, 1
 3     while n < max:
 4         # print(b)
 5         yield b  #yield返回當前狀態的值,程式停在此處
 6         a, b = b, a+b
 7         n = n + 1
 8     return "---done---"  
 9 f = fib(5)
10 f.__next__()
11 X = f.__next__()
12 print(X)
13 print("休息一會兒,馬上就回來了")
14 Y = f.__next__()
15 print(Y)
16 print("又走了...")
17 Z = f.__next__()
18 print(Z)
19 >>>
20 1
21 休息一會兒,馬上就回來了
22 2
23 又走了...
24 3

能看到這,那你又又又又又又要學到了:抓異常、抓異常、抓異常。重要的事情說三遍!!!

 1 def fib(max):
 2     n, a, b = 0, 0, 1
 3     while n < max:
 4         # print(b)
 5         yield b  #yield返回當前狀態的值,程式停在此處
 6         a, b = b, a+b
 7         n = n + 1
 8     return "---done---"
 9 g = fib(8)
10 while True:
11     try:
12         x = next(g)  # 等價於 x = g.__next__()
13         print("value:", x)
14     except StopIteration as e: #當出現StopIteration時執行下麵的代碼
15         print("Generator return value", e.value)
16         break
17 
18 >>>
19 value: 1
20 value: 1
21 value: 2
22 value: 3
23 value: 5
24 value: 8
25 value: 13
26 value: 21
27 Generator return value ---done---

生成器示例高級,實現並行:

import  time
def consum(name):
    print("%s 要來吃包子了" % (name))
    while True:
        baozi = yield
        print("%s個包子被%s吃了" % (baozi, name))

def product(name):
    d = consum("flb")
    d2 = consum("wxl")
    d.__next__() # next喚醒yield,不會給yield傳值
    d2.__next__()
    print("%s要來做包子了" %(name))
    for i in  range(3):
        time.sleep(1)
        print("%s做了%s個包子" %(name,i))
        d.send(i)  # send喚醒yield,會給yield傳值
        d2.send(i)
product("TJ")

>>>
flb 要來吃包子了
wxl 要來吃包子了
TJ要來做包子了
TJ做了0個包子
0個包子被flb吃了
0個包子被wxl吃了
TJ做了1個包子
1個包子被flb吃了
1個包子被wxl吃了
TJ做了2個包子
2個包子被flb吃了
2個包子被wxl吃了

END!!!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 有一個問題, 給定一個物體的運動軌跡, 包含時間和坐標的數組, 如何使用這個數據來預測物體未來的運動走勢?? 本文提供了一個很簡單的方式去實現這個演算法. 效果夠用, 又簡單, 有一定的準確程度. 緣由 以前做過的一些手機應用, 沒有做動畫的 , 也沒做手勢. 這個做起來挺麻煩的. 最近開始了新 ...
  • 雖然Vue 3還沒有正式發佈,但是熱愛新技術的我早已按捺不住自己的內心,開始嘗試在小項目中使用它了。 1.根據這篇《今日凌晨Vue3 beta版震撼發佈,竟然公開支持腳手架項目!》我搭建了一個Vue 3的腳手架項目,用這種方式搭建的腳手架項目不僅僅只有vue是新版的,就連vue-router、vue ...
  • 1.1什麼是數據結構? 官方解釋: 數據結構是一門研究非數值計算的程式設計問題中的操作對象,以及他們之間的關係和操作等相關問題的學科。 大白話 : 數據結構就是把數據元素按照一定的關係組織起來的集合,用來組織和存儲數據 1.2數據結構分類? 傳統上。我們可以把數據結構分為邏輯結構和物理結構兩大類。 ...
  • 1.前言 這應該是本學期最後一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得瞭如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業過程總結 相比前兩個單元,此單 ...
  • 特別註意:本代碼為 Springboot 工作流 前後分離 + 跨域 版本 (許可權控制到菜單和按鈕) 後臺框架:springboot2.3.0+ Flowable6.5.0+ mybaits+maven+介面 前端頁面:html +vue.js 形式 jquery ajax 非同步跨域 json 格式 ...
  • 對MVC、MVP、MVVM的理解(一) 一、MVC MVC模式再網上的爭議是最大的,一些博客中是這樣描述的 MVC模式的通信是單向的,View觸發事件或數據的提交,到了Controller進行處理邏輯之後,返回Model給View,View再從Model中取出數據,當然View中也會有相應的邏輯。個 ...
  • 一、雜論 1.電腦的存儲方式可以分為兩大基本類型:整數類型和浮點類型。 2.C語言中的數據類型關鍵字: int\long\short\unsigned\char\float\double\signed\void\__Bool\__Complex\__Imaginary 3. 1位元組(byte) = ...
  • Django中模板的用法簡介 1. 模板系統的介紹 Django作為一個Web框架,其模板所需的HTML輸出靜態部分以及動態內容插入 模板由HTML代碼和邏輯控制代碼構成 Django框架的模板語言的語法格式: {{var_name}} 例如:HTML被直接編碼在python代碼中: import ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...