リスト内包表記

Pythonのリスト内包表記(List Comprehension)は、既存のリストや範囲(range)から新しいリストを驚くほどシンプルに、かつ高速に作成するための強力な構文です。通常であれば数行にわたって記述する for ループの処理をわずか1行に凝縮できるため、Pythonらしいクリーンで読みやすいコードを書く上で欠かせないテクニックです。この記事では、リスト内包表記の基本構造から、条件分岐を交えた応用方法、実務での注意点を解説します。
リスト内包表記の基本構文(通常のfor文との対比)
リスト内包表記の基本は、全体を大括弧 [] で囲み、その中に「取り出した要素に施したい処理」と「for文」を同居させる独特なスタイルをとります。
# リスト内包表記の基本構文
[要素に施す式 for 変数 in イテラブル]
言葉だけではイメージしづらいため、「1から5までの数値をそのまま格納したリスト」を生成する処理を、従来の for 文とリスト内包表記で並べて比較してみましょう。どれほどスッキリするかが一目瞭然です。
# 1. 従来の for ループを使った書き方
numbers_old = []
for i in range(1, 6):
numbers_old.append(i)
# 2. リスト内包表記を使ったスマートな書き方
numbers_new = [i for i in range(1, 6)]
print(numbers_new) # 出力: [1, 2, 3, 4, 5]
内包表記では、for i in range(1, 6) で1つずつ取り出された i が、そのまま左端にある i (要素に施す式)に渡され、自動的に新しいリストの要素として組み込まれていきます。空のリストを作って .append() を何度も呼び出す手間がなくなるのが大きなメリットです。
条件付きリスト内包表記(フィルター機能)
リスト内包表記の末尾に if 文を付け加えることで、「特定の条件を満たすデータだけをフィルタリングしてリスト化する」という高度な処理も1行で記述できます。
# 条件付きリスト内包表記(1から10の中の偶数だけを抽出)
even_numbers = [i for i in range(1, 11) if i % 2 == 0]
print(even_numbers) # 出力: [2, 4, 6, 8, 10]
この処理では、まず for によって1から10までの数値が順に取り出され、末尾の if i % 2 == 0 (2で割り切れるか)がチェックされます。この条件が True になった数値だけが、左端の i に届き、無事に新しいリストへと追加されます。
ネスト(入れ子)されたリスト内包表記と2次元リスト
リスト内包表記は、for文をさらにネスト(入れ子)にすることで、行列のような「2次元リスト(リストの中にリストが入った構造)」を一撃で生成することも可能です。
# 3×3の掛け算表(九九の一部のような構造)を生成するネスト
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(matrix)
このコードを実行すると、以下のように入れ子になった美しい2次元配列(行列データ)が組み立てられます。
[[1, 2, 3], [2, 4, 6], [3, 6, 9]]
やりすぎは禁物!「可読性の境界線」
リスト内包表記は非常に便利で、内部的な実行速度も通常のfor文より高速というメリットがありますが、「何でもかんでも1行で書けば良いわけではない」という実務上の重要な注意点があります。
例えば、先ほど紹介した「ネストされたリスト内包表記」や、「ifだけでなくelseによる条件分岐まで詰め込んだ内包表記」は、パッと見たときにコードの意図(何をしようとしているのか)が非常に分かりづらくなります。
# 悪い例:複雑すぎて読む気を無くす内包表記
# result = [x * 2 if x % 2 == 0 else x * 3 for x in range(10) if x > 2]
プログラミングにおいて最も大切なのは「他人が見ても、未来の自分が見ても一瞬で理解できること」です。コードが横に長くなりすぎたり、条件が複雑に絡み合ったりする場合は、無理に内包表記を使わず、あえて通常のfor文やif文を使って複数行に分けて書くのが、実務でバグを出さないためのスマートな判断です。
まとめ
Pythonのリスト内包表記は、データ処理を驚くほどシンプルに美しく整えてくれる強力な武器です。「[式 for 変数 in イテラブル]」という基本の形をベースに、必要に応じて末尾に if によるフィルターを組み合わせることで、リストの生成効率が劇的に向上します。ただし、その強力さゆえに複雑なロジックまで1行に押し込んでしまいがちですので、常に「読みやすさ(可読性)」とのバランスを意識しながら、クリーンなPythonコードを目指していきましょう。