Python實用技法第14篇:根據欄位將記錄分組:itertools.groupby()

Mark發表於2019-02-16

上一篇文章:Python實用技法第13篇:對自定義類物件排序:attrgetter
下一篇文章:Python實用技法第15篇:篩選序列中的元素

1、需求?

有一系列的字典或物件例項,我們想根據某個特定的欄位來分組迭代資料。

2、解決方案?

itertools.groupby()函式在對資料進行分組時特別有用。

例項:

from operator import itemgetter
from itertools import groupby

rows=[
    {`name`:`mark`,`age`:18,`uid`:`110`},
    {`name`:`miaomiao`,`age`:28,`uid`:`160`},
    {`name`:`miaomiao2`,`age`:28,`uid`:`150`},
    {`name`:`xiaohei`,`age`:38,`uid`:`130`},
]

#首先根據age排序
rows.sort(key=itemgetter(`age`))

for age,items in groupby(rows,key=itemgetter(`age`)):
    print(age)
    for i in items:
        print(i)

結果:

18
{`name`: `mark`, `age`: 18, `uid`: `110`}
28
{`name`: `miaomiao`, `age`: 28, `uid`: `160`}
{`name`: `miaomiao2`, `age`: 28, `uid`: `150`}
38
{`name`: `xiaohei`, `age`: 38, `uid`: `130`}

3、分析

Python實用技法第5篇:一鍵多值字典:defaultdict

函式groupby()通過掃描序列找出擁有相同值(或是由引數key指定的函式所返回的值)的序列項,並將它們分組。groupby()建立了一個迭代器,而在每次迭代時都會返回一個值(value)和一個子迭代器(sub_iterator),這個迭代器可以產生所有在該分組內具有該值得項。

在這裡重要的是首先要根據age對資料進行排序。因為groupby()不會排序。

如果只是簡單的根據日期將資料分組到一起,放進一個大的資料結構中以允許進行隨機訪問,那麼利用defaultdict()構建一個一鍵多值字典可能會更好:

from collections import defaultdict

rows=[
    {`name`:`mark`,`age`:18,`uid`:`110`},
    {`name`:`miaomiao`,`age`:28,`uid`:`160`},
    {`name`:`miaomiao2`,`age`:28,`uid`:`150`},
    {`name`:`xiaohei`,`age`:38,`uid`:`130`},
]

rows_by_age=defaultdict(list)
for row in rows:
    rows_by_age[row[`age`]].append(row)
for a in rows_by_age[28]:
    print(a)

結果:

{`name`: `miaomiao`, `age`: 28, `uid`: `160`}
{`name`: `miaomiao2`, `age`: 28, `uid`: `150`}

不考慮排序的話,defaultdict方法一般比groupby快。

上一篇文章:Python實用技法第13篇:對自定義類物件排序:attrgetter
下一篇文章:Python實用技法第15篇:篩選序列中的元素

相關文章