基礎から学ぶPython入門 90日コース | 実践Python - Day 20:内包表記

90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 20:内包表記で「きれいで速い」コードを書く感覚を身につける

Day 20では、Pythonの「内包表記」を学びます。 リスト内包表記・辞書内包表記・セット内包表記・条件付き内包表記を通して、 「for文+if文で書いていた処理を、1行で読みやすく書く」感覚を育てていきます。

内包表記とは何かをイメージする

まずは「普通のfor文」と比べてみる

例として、「1〜5までの2乗のリスト」を作る処理を考えます。

# 通常のfor文で書く場合
squares = []
for n in range(1, 6):
    squares.append(n ** 2)

print(squares)  # [1, 4, 9, 16, 25]
Python

これを内包表記で書くと、次のようになります。

# リスト内包表記で書く場合
squares = [n ** 2 for n in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]
Python
  • 「何を作りたいか」が先頭に来る
  • 「どこから値を取ってくるか」が for の後ろに続く

という形で、「処理の意図」がコンパクトに見えるようになります。

リスト内包表記:一番よく使う内包表記

基本形:[式 for 変数 in イテラブル]

最も基本的な形は次の通りです。

# 1〜10までの数字を2倍したリストを作る
doubles = [n * 2 for n in range(1, 11)]
print(doubles)  # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Python

ここでのポイントは、

  • for n in range(1, 11) が「元データの流れ」を表していること
  • n * 2 が「各要素に対して行う処理」を表していること

です。通常のfor文と対応させて考えると理解しやすくなります。

文字列の加工にも使える

names = ["alice", "bob", "charlie"]

# 先頭を大文字にした名前のリストを作る
capitalized = [name.capitalize() for name in names]
print(capitalized)  # ['Alice', 'Bob', 'Charlie']
Python

条件付きリスト内包表記:フィルタリングを1行で書く

if を後ろに付ける形:[式 for 変数 in イテラブル if 条件]

「偶数だけを取り出したい」「特定の条件を満たすものだけを残したい」といった場合は、 if を後ろに付けることで、フィルタリングを内包表記の中で書けます。

# 1〜10のうち、偶数だけのリストを作る
evens = [n for n in range(1, 11) if n % 2 == 0]
print(evens)  # [2, 4, 6, 8, 10]
Python

通常のfor文で書くとこうなります。

evens = []
for n in range(1, 11):
    if n % 2 == 0:
        evens.append(n)
Python
  • 「条件付きでappendする」処理が、内包表記では「if 条件」で表現されている
  • 「フィルタリング」と「変換」を同時に行える

という点が重要です。

条件付きで値を変える(式の中にifを書く)

もう一歩進んで、「条件によって値を変える」書き方もあります。

# 1〜5の数字について、偶数ならそのまま、奇数なら0にする
values = [n if n % 2 == 0 else 0 for n in range(1, 6)]
print(values)  # [0, 2, 0, 4, 0]
Python

ここでは、

  • n if n % 2 == 0 else 0 が「条件付きの式」
  • for n in range(1, 6) が「元データの流れ」

という構造になっています。

辞書内包表記:キーと値をまとめて作る

基本形:{キー式: 値式 for 変数 in イテラブル}

辞書内包表記は、「キーと値のペアをまとめて作る」ための内包表記です。

# 1〜5の数字をキー、その2乗を値とする辞書を作る
square_dict = {n: n ** 2 for n in range(1, 5 + 1)}
print(square_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Python

通常のfor文で書くとこうなります。

square_dict = {}
for n in range(1, 6):
    square_dict[n] = n ** 2
Python
  • 「キー」と「値」を同時に指定できる
  • 「辞書を初期化するコード」がコンパクトになる

という点が辞書内包表記のメリットです。

条件付き辞書内包表記

例えば、「偶数だけを辞書に入れたい」場合は、if を後ろに付けます。

# 偶数だけをキーにし、その2乗を値とする辞書
even_square_dict = {n: n ** 2 for n in range(1, 11) if n % 2 == 0}
print(even_square_dict)  # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
Python

セット内包表記:重複を自動で取り除く

基本形:{式 for 変数 in イテラブル}

セット内包表記は、「重複を自動で取り除きたい」場合に便利です。

words = ["apple", "banana", "apple", "orange", "banana"]

# 重複を取り除いた単語の集合を作る
unique_words = {word for word in words}
print(unique_words)  # {'apple', 'banana', 'orange'} など(順序は保証されません)
Python

ここでのポイントは、

  • セット(set)は「順序なし・重複なし」のコレクションであること
  • 内包表記で作ると、「重複を取り除いた集合」を簡単に作れること

です。

条件付きセット内包表記

例えば、「5文字以上の単語だけを集合にしたい」場合は、次のように書きます。

words = ["apple", "banana", "app", "orange", "ban"]

long_words = {word for word in words if len(word) >= 5}
print(long_words)  # {'apple', 'banana', 'orange'} など
Python

内包表記を使った「ちょっと実用的な」例

メールアドレスのドメイン一覧を作る

Day 19で扱ったメールアドレス抽出と組み合わせて、 「メールアドレスからドメインだけを取り出し、重複なしの集合にする」例です。

emails = [
    "info@example.com",
    "support@example.com",
    "user@my-service.jp",
    "admin@my-service.jp",
]

# ドメイン部分(@の後ろ)だけを取り出して集合にする
domains = {email.split("@")[1] for email in emails}
print(domains)  # {'example.com', 'my-service.jp'} など
Python

ここでは、

  • email.split("@")[1] で「@の後ろの部分」を取り出していること
  • セット内包表記で「重複を自動で取り除いている」こと

がポイントです。

テキスト中の単語を「長さ別」に分類する辞書

text = "Python is fun and powerful"

words = text.split()  # ['Python', 'is', 'fun', 'and', 'powerful']

# 単語を「長さ」をキーにして分類する辞書を作る
length_dict = {len(word): [w for w in words if len(w) == len(word)] for word in words}
print(length_dict)
# 例: {6: ['Python'], 2: ['is'], 3: ['fun', 'and'], 8: ['powerful']}
Python

この例は少し高度ですが、

  • 外側の辞書内包表記で「キー(長さ)」を決めている
  • 内側のリスト内包表記で「その長さの単語だけを集めている」

という構造になっています。

Day 20ミニテンプレート:内包表記練習スクリプト

最後に、Day 20で学んだ内容をまとめて試せる「内包表記練習スクリプト」のテンプレートを示します。

# day20_comprehension_practice.py
# 内包表記の練習用スクリプト

def list_comprehension_examples():
    # 1〜10の2乗
    squares = [n ** 2 for n in range(1, 11)]
    print("1〜10の2乗:", squares)

    # 偶数だけ
    evens = [n for n in range(1, 11) if n % 2 == 0]
    print("偶数だけ:", evens)

    # 条件付きで値を変える
    values = [n if n % 2 == 0 else 0 for n in range(1, 6)]
    print("偶数はそのまま、奇数は0:", values)


def dict_comprehension_examples():
    # 1〜5の数字をキー、その2乗を値とする辞書
    square_dict = {n: n ** 2 for n in range(1, 6)}
    print("1〜5の2乗辞書:", square_dict)

    # 偶数だけの辞書
    even_square_dict = {n: n ** 2 for n in range(1, 11) if n % 2 == 0}
    print("偶数だけの2乗辞書:", even_square_dict)


def set_comprehension_examples():
    words = ["apple", "banana", "apple", "orange", "banana"]
    unique_words = {word for word in words}
    print("重複なしの単語集合:", unique_words)

    long_words = {word for word in words if len(word) >= 6}
    print("6文字以上の単語集合:", long_words)


def main():
    print("=== Day 20:内包表記練習スクリプト ===")
    list_comprehension_examples()
    print("--------------------")
    dict_comprehension_examples()
    print("--------------------")
    set_comprehension_examples()


if __name__ == "__main__":
    main()
Python

Day 20のまとめ

Day 20では、内包表記を通して、

  • リスト内包表記で「変換」と「フィルタリング」をコンパクトに書く感覚
  • 辞書内包表記で「キーと値のペア」をまとめて作る方法
  • セット内包表記で「重複を自動で取り除く集合」を作る方法
  • 条件付き内包表記で「条件によって値を変える/残す」書き方

をステップバイステップで体験していただきました。

ここまで来ると、「for文+if文で書いていた処理を、内包表記で読みやすく書き直せる」という感覚が少し育っているはずです。 この感覚は、今後の実践Python編でデータ処理・テキスト処理・集計などを行ううえで、コードをきれいに保つための強力な武器になっていきます。

タイトルとURLをコピーしました