[Python] list flatten

最近剛好碰到需要做 list flatten 的行為

網路上查了一下, 順便做了一點不專業的比較

故事是這樣的

今天我有一個 list 中的 list

tmp_list = [[1, 2, 3, 4], [5, 6, 7, 8]]

我今天想要做的事情就是把他平扁化, 也就是變成 [1, 2, 3, 4, 5, 6, 7, 8]

查到有兩種作法

1. 利用 itertools

import itertools
list(itertools.chain.from_iterable(tmp_list))
#  [1, 2, 3, 4, 5, 6, 7, 8]

正當我覺的還要多 import module 不太滿意的時候, 看到了第二種作法

2. 利用 sum
sum(tmp_list, [])
#  [1, 2, 3, 4, 5, 6, 7, 8]

頓時讓我覺的好聰明阿, 不過一般人來講應該會寫的第三種

3. 利用 list comprehensive
[item for sub_list in tmp_list for item in sub_list]
#  [1, 2, 3, 4, 5, 6, 7, 8]

那順便做一個大的 list 來試試看哪個比較威XD


import itertools

def make_list():
    return [range(100) for i in range(1000)]

@profile
def merge_iter(tmp_list):
    return list(itertools.chain.from_iterable(tmp_list))

@profile
def merge_sum(tmp_list):
    return sum(tmp_list, []) 

@profile
def merge_comph(tmp_list):
    return [item for sub_list in tmp_list for item in sub_list]

if __name__ == '__main__':
    tmp_list = make_list()
    merge_iter(tmp_list)
    merge_sum(tmp_list)
    merge_comph(tmp_list)

不負責任的跑完結果如下
Timer unit: 1e-06 s

File: tmp.py
Function: merge_iter at line 6
Total time: 0.000879 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     6                                           @profile
     7                                           def merge_iter(tmp_list):
     8         1          879    879.0    100.0      return list(itertools.chain.from_iterable(tmp_list))

File: tmp.py
Function: merge_sum at line 10
Total time: 0.101459 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    10                                           @profile
    11                                           def merge_sum(tmp_list):
    12         1       101459 101459.0    100.0      return sum(tmp_list, [])

File: tmp.py
Function: merge_comph at line 14
Total time: 0.04173 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    14                                           @profile
    15                                           def merge_comph(tmp_list):
    16    101001        41730      0.4    100.0      return [item for sub_list in tmp_list for item in sub_list]

簡易的結論, 最短的其實背後缺乏效率, 反倒是用 itertool 結果最為迅速

當然我覺的還是要看使用場合, 如果只是小 list 合併, 用sum應該是可以快速驗證結果的coding流程

留言

這個網誌中的熱門文章

[Linux] Linux下查詢硬體記憶體資訊 Memory Information

[Other] Chrome 重新整理所有開啟頁面

[Python] Simple Socket Server