リスト内包表記を使おう
リスト内包表記は、リストを簡潔に作成するための Python の強力な構文です。for ループを使ったリスト生成を1行で書けるようになり、コードがより読みやすくなります。このレッスンでは、リスト内包表記の基本から条件付きの書き方までを学びます。
リスト内包表記とは
リスト内包表記(list comprehension)は、リストを簡潔に作成するための構文です。for 文を使ったリスト生成を、より短く読みやすいコードで書くことができます。
まずは簡単な例を見てみましょう。1 から 5 までの数を2倍にしたリストを作成します。
doubled = [x * 2 for x in range(1, 6)] print(doubled) # => [2, 4, 6, 8, 10]
このように、リスト内包表記を使うと1行でリストを作成できます。
for ループとの比較
リスト内包表記の良さを理解するために、従来の for ループを使った書き方と比較してみましょう。
まず、for ループで 1 から 5 までの数を2倍にしたリストを作成する場合は、次のように書きます。
doubled = [] for x in range(1, 6): doubled.append(x * 2) print(doubled) # => [2, 4, 6, 8, 10]
これをリスト内包表記で書くと、次のように1行になります。
doubled = [x * 2 for x in range(1, 6)] print(doubled) # => [2, 4, 6, 8, 10]
どちらも同じ結果になりますが、リスト内包表記の方がコードが短く、何をしているかが一目で分かります。
基本構文
リスト内包表記の基本構文は次の通りです。
[式 for 変数 in イテラブル]
- 式: 各要素に対して計算する内容
- 変数: イテラブルから取り出した各要素
- イテラブル: リストや range() など、ループで使えるもの
例えば、文字列のリストをすべて大文字に変換する場合は次のように書きます。
words = ["apple", "banana", "cherry"] upper_words = [word.upper() for word in words] print(upper_words) # => ['APPLE', 'BANANA', 'CHERRY']
数値のリストの各要素を2乗する場合は次のようになります。
numbers = [1, 2, 3, 4, 5] squares = [n ** 2 for n in numbers] print(squares) # => [1, 4, 9, 16, 25]
条件付きリスト内包表記
リスト内包表記では、if を使って条件を満たす要素だけを抽出することもできます。
[式 for 変数 in イテラブル if 条件]
例えば、1 から 10 までの偶数だけを抽出するには次のように書きます。
evens = [x for x in range(1, 11) if x % 2 == 0] print(evens) # => [2, 4, 6, 8, 10]
if x % 2 == 0 という条件により、2で割り切れる数(偶数)だけがリストに含まれます。
リストから特定の条件を満たす要素だけを抽出する例も見てみましょう。
scores = [85, 42, 90, 65, 38, 72] passed = [score for score in scores if score >= 60] print(passed) # => [85, 90, 65, 72]
60 点以上のスコアだけが passed リストに含まれます。
式と条件の組み合わせ
条件でフィルタリングしながら、各要素に対して計算を行うこともできます。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] even_squares = [n ** 2 for n in numbers if n % 2 == 0] print(even_squares) # => [4, 16, 36, 64, 100]
この例では、偶数だけを抽出し、それぞれを2乗しています。
可読性とのバランス
リスト内包表記は便利ですが、複雑になりすぎると読みにくくなります。1行で書けるからといって、常にリスト内包表記を使うべきとは限りません。
次のような場合は、for ループを使った方が読みやすくなることがあります。
- 複数の処理を行う場合
- 条件が複雑な場合
- ネスト(入れ子)が深くなる場合
例えば、次のような複雑なリスト内包表記は避けた方がよいでしょう。
# 読みにくい例 data = "apple,#comment,banana,,cherry" result = [x.upper() for x in data.split(",") if len(x.strip()) > 0 and not x.startswith("#")] print(result) # => ['APPLE', 'BANANA', 'CHERRY']
このような場合は、for ループで書いた方が意図が伝わりやすくなります。
# 読みやすい例 data = "apple,#comment,banana,,cherry" result = [] for x in data.split(","): if len(x.strip()) > 0 and not x.startswith("#"): result.append(x.upper()) print(result) # => ['APPLE', 'BANANA', 'CHERRY']
コードの読みやすさを優先し、シンプルな変換や抽出にリスト内包表記を使うようにしましょう。
まとめ
- リスト内包表記は
[式 for 変数 in イテラブル]の構文でリストを作成する - for ループを使った書き方より簡潔にリストを生成できる
ifを追加して条件付きのリスト生成ができる:[式 for 変数 in イテラブル if 条件]- 複雑な処理には for ループを使い、コードの可読性を優先する
演習に挑戦