使用迭代器接收資料並自動停止
假設有一個 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
- 迭代器,迭代器塊和資料管道
- 使用**迭代器**獲取Cifar等常用資料集
- 【IMPDP】使用IMPDP自動建立使用者並完成資料的匯入
- python迭代器資料整理Python
- 如何使用 jq 接收 blob 資料
- 啟動和停止資料庫.資料庫
- 使用指標接收器時,值物件自動取指標的奇怪問題指標物件
- 怎樣啟動停止重啟MySQL資料庫伺服器MySql資料庫伺服器
- AIX下自動啟動/停止Oracle資料庫AIOracle資料庫
- 利用dbstart和dbshut指令碼自動啟動和停止資料庫的問題指令碼資料庫
- win10停止自動更新操作 win10停止自動更新方法Win10
- .net接收post請求並把資料轉為字典格式
- 用doPost來接收post傳過來的資料並存入mysql資料庫MySql資料庫
- linux平臺下監聽器和Oracle的自動啟動與停止LinuxOracle
- 使用postman傳送資料,springmvc接收資料的問題PostmanSpringMVC
- 觸發器實現表資料自動更新觸發器
- Python自制微信機器人:群發訊息、自動接收好友Python機器人
- [springboot]一啟動就自動停止了Spring Boot
- 為什麼使用Socket接收時丟失資料?
- 澳鵬Appen:自動駕駛浪潮下,如何給技術迭代插上資料的“翅膀”?APP自動駕駛
- win10系統如何停止強制自動更新_win10停止強制自動更新的方法Win10
- 使用自動儲存管理 (ASM)建立資料庫ASM資料庫
- Oracle TNSListener服務啟動後自動停止問題Oracle
- linux下Oracle自動啟動與停止總結LinuxOracle
- 2 Day DBA-使用基於SQL的管理工具管理資料庫-啟動和停止監聽器SQL資料庫
- Java 包裝類:原始資料型別與迭代器Java資料型別
- 9i上JOB停止自動執行
- 達觀資料:Selenium使用技巧與機器人流程自動化實戰機器人
- 使用Nginx+Hexo光速搭建部落格並實現伺服器自動部署NginxHexo伺服器
- 迭代器
- Java:設計與使用迭代器薦Java
- servlet接收xml資料流[java]ServletXMLJava
- VMware在windows自啟動,並開啟虛擬機器Windows虛擬機
- 使用Jenkins持續整合前端專案並自動化部署到Nginx伺服器Jenkins前端Nginx伺服器
- Python 自動化拉取 MySQL 資料並建表裝載到 OraclePythonMySqlOracle
- 爬取Arcconf文件教程並自動生成Gitbook文件顯示 - 資料獲Git
- 自動佈署伺服器環境,並利用 Git 實現原生程式碼自動同步到伺服器!伺服器Git