Pythonで多次元リストを一次元に平坦化(flatten)する方法
Pythonでデータ処理を行う際、多次元リスト(ネストされたリスト)を一次元のリストに変換したい、つまり「平坦化(flatten)」したいという状況はよくあります。この記事では、Pythonで多次元リストを効率的かつ簡潔に平坦化する様々な方法を、短いサンプルコードとともに解説します。
目次
flatten(平坦化)とは?
平坦化とは、複数のリストが入れ子になった構造(多次元リスト)を、単一のリスト(一次元リスト)に変換する操作のことです。
例:
元の多次元リスト: [[1, 2], [3, 4, 5], [6]]
平坦化したリスト: [1, 2, 3, 4, 5, 6]
この操作は、データを統一的に処理したい場合や、特定のアルゴリズムに適合させたい場合によく利用されます。
Pythonでリストを平坦化する方法
Pythonでリストを平坦化するには、いくつかのテクニックがあります。リストの深さ(ネストのレベル)やデータ構造によって最適な方法が異なります。
1. リスト内包表記(簡単なネストの場合)
最も一般的でPythonicな方法の一つは、リスト内包表記を使うことです。これは特に、ネストが1階層(リストの中にリストがある状態)の場合に非常に効果的です。
# 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()関数は通常、数値の合計を計算するために使われますが、初期値に空のリストを指定することで、リストを結合する用途にも使えます。ただし、パフォーマンスの観点から、大きなリストには推奨されません。
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()関数は、複数のイテラブルを一つのシーケンスとして扱いたい場合に非常に強力です。特に、大きなリストやパフォーマンスが重要な場合に最適です。
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. 再帰関数(任意の深さのネストに対応)
もしリストのネストが任意の深さになる可能性がある場合、上記の単純な方法では対応できません。そのような場合は、再帰関数を定義して平坦化するのが一般的です。
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爆速講座



