Pythonで多次元リストを一次元に平坦化(flatten)する方法


Pythonでデータ処理を行う際、多次元リスト(ネストされたリスト)を一次元のリストに変換したい、つまり「平坦化(flatten)」したいという状況はよくあります。この記事では、Pythonで多次元リストを効率的かつ簡潔に平坦化する様々な方法を、短いサンプルコードとともに解説します。

flatten(平坦化)とは?

平坦化とは、複数のリストが入れ子になった構造(多次元リスト)を、単一のリスト(一次元リスト)に変換する操作のことです。

例:

元の多次元リスト: [[1, 2], [3, 4, 5], [6]]
平坦化したリスト: [1, 2, 3, 4, 5, 6]

この操作は、データを統一的に処理したい場合や、特定のアルゴリズムに適合させたい場合によく利用されます。


Pythonでリストを平坦化する方法

Pythonでリストを平坦化するには、いくつかのテクニックがあります。リストの深さ(ネストのレベル)やデータ構造によって最適な方法が異なります。

1. リスト内包表記(簡単なネストの場合)

最も一般的でPythonicな方法の一つは、リスト内包表記を使うことです。これは特に、ネストが1階層(リストの中にリストがある状態)の場合に非常に効果的です。

Python
 
# 1階層のネスト
nested_list = [[1, 2], [3, 4], [5]]

flattened_list = [item for sublist in nested_list for item in sublist]

print(flattened_list)
# 出力: [1, 2, 3, 4, 5]

この方法は、可読性が高く、パフォーマンスも良好です。

2. sum()関数を使う方法(非推奨な点に注意)

sum()関数は通常、数値の合計を計算するために使われますが、初期値に空のリストを指定することで、リストを結合する用途にも使えます。ただし、パフォーマンスの観点から、大きなリストには推奨されません。

Python
 
nested_list = [[1, 2], [3, 4], [5]]

flattened_list = sum(nested_list, [])

print(flattened_list)
# 出力: [1, 2, 3, 4, 5]

この方法はコードが短く見えますが、内部的にはリストのコピーが繰り返されるため、効率が悪くなります。

3. itertools.chain()を使う方法(パフォーマンス重視)

itertoolsモジュールのchain()関数は、複数のイテラブルを一つのシーケンスとして扱いたい場合に非常に強力です。特に、大きなリストやパフォーマンスが重要な場合に最適です。

Python
 
import itertools

nested_list = [[1, 2], [3, 4], [5]]

flattened_list = list(itertools.chain(*nested_list))

print(flattened_list)
# 出力: [1, 2, 3, 4, 5]

*nested_listは、nested_listをアンパックして、chain()関数に個々のサブリストを引数として渡します。これはchain([1, 2], [3, 4], [5])と等価です。


4. 再帰関数(任意の深さのネストに対応)

もしリストのネストが任意の深さになる可能性がある場合、上記の単純な方法では対応できません。そのような場合は、再帰関数を定義して平坦化するのが一般的です。

Python
 
def flatten_recursive(nested_list):
    flat_list = []
    for item in nested_list:
        if isinstance(item, list):
            flat_list.extend(flatten_recursive(item)) # リストなら再帰的に処理
        else:
            flat_list.append(item) # リストでなければ追加
    return flat_list

deeply_nested_list = [1, [2, 3], [4, [5, 6]], 7]

flattened_list = flatten_recursive(deeply_nested_list)

print(flattened_list)
# 出力: [1, 2, 3, 4, 5, 6, 7]

この関数は、リストの要素がさらにリストであるかどうかをチェックし、リストであれば自身を呼び出して深く潜っていきます。


まとめ

Pythonで多次元リストを平坦化する方法は、リストのネストの深さやパフォーマンス要件によって選び方が異なります。

  • 1階層のネストならリスト内包表記が最も簡潔で分かりやすい。

  • パフォーマンスを重視するなら**itertools.chain()**が優れている。

  • 任意の深さのネストに対応するには再帰関数を用いる。

これらのテクニックを状況に応じて使い分け、Pythonでのデータ処理をより効率的に行いましょう!

らくらくPython塾 – 読むだけでマスター

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座