python groupby 筆記

itertool::groupby(iterable[, keyFunc=None]) 
  1. groupby, 將你的一維陣列中每個元素,依照特定的條件再各自分成一組一組的。(相鄰同 key 的元素會自成一坨)
  2. iterable, 能夠尋訪並且吐出 element 的變數
  3. keyFunc, 將 element 代入能夠得到 key 的 function。
    • def key1(ele): return ele % 3 -> 相鄰同餘 3 的元素自成一坨
    • def key2(ele): return ele[1] -> 相鄰並且第二欄位相同的元素自成一坨
    • def key3(ele): return ele.zone -> 相鄰並且欄位zone相同的元素自成一坨

Python 3 Doc

https://docs.python.org/3/library/itertools.html#itertools.groupby

Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each element. If not specified or is None, key defaults to an identity function and returns the element unchanged. Generally, the iterable needs to already be sorted on the same key function.

行為

分類方式會線性尋訪,依序代入 element 到 keyFunc 取 key。

  • key 與上一個 element 的 key 一樣: 被加入原來 group
  • 若是不一樣: 被加入到新建的 group

當 keyFunc 沒給的預設行為

預設 keyFunc 會是 lambda x: x 自身當一個 key。故預設行為會是將 iterable 中相同 element 的圈一組。

一定要sort 好

因為它是只記錄上一次的 key 以及是線性尋訪,所以你若是要依 key 來分類的話,請一定要先 sort 好。否則會東一塊西一塊。

輸出

一個含有每個 group 2-tuple 的 iter。
group 2-tuple 中的 2nd 又是一個 group 內部的 subiter。

[(key1, iter1), (key2, iter2), (key3, iter3), ...]

例子

例子 1
groupby("hello")
  • 預設 keyFunc -> 自身即是 key -> 一樣字母的一國
  • 四國, 各是 h, e, l, o 這四個 key
  • 每一國內部還能再去取得實際字母
output
as = []
for k, g in itertools.groupby("hello"):
    as.append( [k, list(g)] )
    
print(as)
[
    ["h", ["h"]], 
    ["e", ["e"]], 
    ["l", ["l", "l"]], 
    ["o", ["o"]]
]
例子 2
groupby("ABBBCCCCAAA") # 沒 sort 的
output
[
    ["A", ["A"]], 
    ["B", ["B","B","B"]], 
    ["C", ["C","C","C","C"]], 
    ["A", ["A","A","A","A",]]
]
例子 3:
groupby(range(10), lambda x: x // 3)

0到9的數列,將商數相同的分一組

output
[
    [0, [0,1,2]],     
    [1, [3,4,5]],     
    # 3, 4, 5 這 3個數字透過 keyFunc

    # 都會得到一樣的商數 1

    # 所以被分在同一組

    [2, [6,7,8]],
    [3, [9]
]
例子 4:
groupby(
    (
        ("Dog", "land"),
        ("Cat", "land"),
        ("Eagle", "bird"),
        ("Chicken Attack", "bird"),
        ("Whale", "sea"),    
    ),
    lambda x: x[1]
)

將 element 2-tuple 的第二數值當 key
所以 Dog 跟 Cat 會因為傳入的 ("Dog", "land") 與 ("Cat", "land")
進 lambda x: x[1] 得到相同的 "land" 而分在同一組

0到9的數列,將商數相同的分一組

output
[
    ["land", ["Dog", "Cat"],    
    ["bird", ["Eagle", "Chicken Attack"],
    ["sea", ["Whale"],
]
comments powered by Disqus