- Python進階編程:編寫更高效、優雅的Python代碼
- 劉宇宙 謝東 劉艷
- 598字
- 2021-04-30 12:39:46
3.3.3 記錄分組
在實際操作字典或實例序列中的記錄時,我們需要實現分組迭代訪問,如根據某個特定的字段比如date來分組迭代訪問。
對于數據分組操作來說,itertools.groupby()函數非常實用。假設我們已經有下列的字典列表:
done_record = [ {'done': 'read book', 'date': '07/01/2020'}, {'done': 'work', 'date': '07/04/2020'}, {'done': 'family chat', 'date': '07/02/2020'}, {'done': 'run', 'date': '07/03/2020'}, {'done': 'sport', 'date': '07/02/2020'}, {'done': 'read 20 pages', 'date': '07/02/2020'}, {'done': 'run 5km', 'date': '07/01/2020'}, {'done': 'sport 2 hours', 'date': '07/04/2020'}, ]
需要在按date分組后的數據塊上進行迭代。首先需要按照指定的字段(比如date)排序,然后調用itertools.groupby()函數,代碼如下:
from operator import itemgetter from itertools import groupby done_record = [ {'done': 'read book', 'date': '07/01/2020'}, {'done': 'work', 'date': '07/04/2020'}, {'done': 'family chat', 'date': '07/02/2020'}, {'done': 'run', 'date': '07/03/2020'}, {'done': 'sport', 'date': '07/02/2020'}, {'done': 'read 20 pages', 'date': '07/02/2020'}, {'done': 'run 5km', 'date': '07/01/2020'}, {'done': 'sport 2 hours', 'date': '07/04/2020'}, ] # Sort by the desired field first done_record.sort(key=itemgetter('date')) # Iterate in groups for date, items in groupby(done_record, key=itemgetter('date')): print(date) for i in items: print(' ', i)
groupby()函數掃描整個序列并且查找連續相同值(或者根據指定key函數返回值相同的元素序列)。
在每次迭代的時候,groupby()函數會返回一個值和一個迭代器對象,該迭代器對象可以生成元素值全部等于上面元素序列中元素值的對象。
一個非常重要的準備步驟是要根據指定的字段對數據進行排序。由于groupby()函數僅僅檢查連續的元素,如果事先沒有對元素完成排序,我們將得不到想要的結果。
如果僅僅只是想根據date字段將數據分組到一個大的數據結構中,并且允許隨機訪問,那么最好使用defaultdict()函數來構建一個多值字典,示例如下:
from collections import defaultdict record_by_date = defaultdict(list) for record in done_record: record_by_date[record['date']].append(record)
這樣,我們就可以很輕松地對每個指定日期訪問對應的記錄,代碼如下:
for record in record_by_date['07/01/2012']: print(record)
在該示例中,沒有必要先將記錄排序。如果對內存占用不是很關心,這種方式會比先排序,然后再通過groupby()函數迭代的方式運行得快一些。