使用迭代器接收資料並自動停止
假設有一個 Redis 集合,裡面有 N 條資料,你不停從裡面lpop資料,直到某一條資料的值為'Stop'字串為止(已知裡面必有一條資料為'Stop'字串,但其位置不知道)。
這個需求看起來很簡單,於是你立刻就著手寫出了程式碼:
import redis client = redis.Redis() def read_data(): datas = [] while True: data = client.lpop().decode() if data == 'Stop': break datas.append(data) return datas
現在問題來了,如果 Redis 裡面的資料非常多,已經超過了你的記憶體容量怎麼辦?資料全部放在datas列表裡面再返回顯然是不可取的做法。
好在,這些資料讀取出來以後,會傳給一個parse函式,並且這個函式是一條一條處理資料的,它處理完成以後,就可以把資料丟棄了。
於是你可能會這樣改寫程式碼:
import redis client = redis.Redis() def read_data(): while True: data = client.lpop().decode() if data == 'Stop': break parse(data)
但我們知道,在編碼規範和軟體工程裡面,建議一個函式,它應該只做一件事情,而現在read_data()函式卻做了兩件事情:1. 從 Redis 裡面讀取資料。2.呼叫parse()函式。
那麼我們有沒有辦法把他們區分開來呢?如何讓read_data能返回資料,但是又不會把記憶體撐爆呢?
這個時候,我們就可以使用生成器來解決問題:
import redis client = redis.Redis() def read_data(): while True: data = client.lpop().decode() if data == 'Stop': break yield data def parse_data(): for data in read_data(): parse(data)
在這個程式碼裡面,read_data變成了生成器函式,它返回一個生成器,對生成器進行迭代的時候,每次返回一條資料,這一條資料立即傳給parse()函式。整個過程源源不斷,生生不息。不需要額外建立一個列表用來存放資料。
那麼程式碼還能不能繼續簡化呢?此時我們就可以使用iter關鍵字了。
使用了iter關鍵字的效果如下圖所示:
import redis client = redis.Redis() def read_data(): data = client.lpop().decode() return data def parse_data(): for data in iter(read_data, 'Stop'): parse(data)
其中,read_data現在每執行一次只會返回列表最左邊的資料。但是當我們直接使用iter(read_data, 'Stop')的時候,就會得到一個迭代器。對這個迭代器進行迭代,相當於在While True裡面不停執行read_data函式,直到某一次迭代的時候,read_data函式返回了Stop,就停止。
當然如果你想炫技的話,還可以進一步簡化:
import redis client = redis.Redis() def parse_data(): for data in iter(lambda: client.lpop().decode(), 'Stop'): parse(data)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1834/viewspace-2835902/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python遍歷迭代器自動鏈式處理資料Python
- 使用PowerShell/CMD自動化安裝並配置MySQL資料庫MySql資料庫
- 使用**迭代器**獲取Cifar等常用資料集
- 如何使用 jq 接收 blob 資料
- 抖音開放平臺,接收進入會話事件,接收私信並自動回覆私信 企業號私信自動回覆介面會話事件
- 編寫可調模板並使用自動調諧器
- win10停止自動更新操作 win10停止自動更新方法Win10
- .net接收post請求並把資料轉為字典格式
- [springboot]一啟動就自動停止了Spring Boot
- 使用postman傳送資料,springmvc接收資料的問題PostmanSpringMVC
- 如何停止使用console.log並開始用瀏覽器的debugger瀏覽器
- [譯]如何停止使用 console.log() 並開始使用瀏覽器除錯程式碼瀏覽器除錯
- Veritas Enterprise Vault 15.0 (Windows) - 自動捕獲資料並歸檔資訊Windows
- Veritas Enterprise Vault 15.1 (Windows) - 自動捕獲資料並歸檔資訊Windows
- win10系統如何停止強制自動更新_win10停止強制自動更新的方法Win10
- Pytest自動化發現測試資料並進行資料驅動-支援YAML/JSON/INI/CSV資料檔案YAMLJSON
- 觸發器實現表資料自動更新觸發器
- Python自制微信機器人:群發訊息、自動接收好友Python機器人
- 達觀資料:Selenium使用技巧與機器人流程自動化實戰機器人
- go嘗試從channel c接收資料,並檢查channel是否關閉Go
- 澳鵬Appen:自動駕駛浪潮下,如何給技術迭代插上資料的“翅膀”?APP自動駕駛
- Qml接收QList<QVariantMap> 資料
- Java 包裝類:原始資料型別與迭代器Java資料型別
- Python 自動化拉取 MySQL 資料並建表裝載到 OraclePythonMySqlOracle
- vmware設定共享資料夾,並保持為開機自動掛載
- 爬取Arcconf文件教程並自動生成Gitbook文件顯示 - 資料獲Git
- 使用Nginx+Hexo光速搭建部落格並實現伺服器自動部署NginxHexo伺服器
- 使用Jenkins持續整合前端專案並自動化部署到Nginx伺服器Jenkins前端Nginx伺服器
- python使用flask接收前端資料,處理後返回結果PythonFlask前端
- label studio 結合 MMDetection 實現資料集自動標記、模型迭代訓練的閉環模型
- 迭代器
- VMware在windows自啟動,並開啟虛擬機器Windows虛擬機
- Python進階:迭代器與迭代器切片Python
- windows10取消自動更新在哪_windows10停止自動更新怎麼操作Windows
- 自動佈署伺服器環境,並利用 Git 實現原生程式碼自動同步到伺服器!伺服器Git
- 何時停止設計並啟動實施程式設計? - Alter程式設計
- 使用Jenkins自動構建Android應用打包並上傳JenkinsAndroid
- 使用chrome瀏覽器驅動自動開啟瀏覽器Chrome瀏覽器