[Pythonクイズ]f文字列最強なんですが、そうじゃない場合もありますよ どんなときか分かりますか?Pythonステップアップクイズ

Pythonのf文字列って使いやすいじゃないですか。ついつい使っちゃいますよね。でも、f文字列が適していない場合もあるんです。そこがformatメソッドの出番なんですよね。

» 2025年12月09日 05時00分 公開
[かわさきしんじDeep Insider編集部]
「Pythonステップアップクイズ」のインデックス

連載目次

formatメソッドを使って書き替えてみよう formatメソッドを使って書き替えてみよう

【問題】

 以下のmake_greeting関数はlangに受け取った言語コードに合わせて、f文字列にnameの値を埋め込んだものを返す。これは問題なく動作するが、対応する言語コードが増えるとif文がどんどん長くなっていく(出力を見ると言語コードに'fr'を渡したときにはelse節が実行されている)。文字列のformatメソッドを使って、よりシンプルに書き直してみよう。

def make_greeting(lang, name):
    if lang == 'ja':
        return f'こんにちは {name}さん'
    elif lang == 'es':
        return f'Hola {name}'

        ...    # 他にもelif節がたくさん

    else:
        return f'Hello {name}'
        
greeting = make_greeting('ja', 'kawasaki')
print(greeting)  # こんにちは kawasakiさん

greeting = make_greeting('fr', 'kawasaki')
print(greeting)  # Hello kawasaki

文字列のformatメソッドを使って書き直してみよう

LLMはうまく書き直せるかな?

 というわけで、今回は問題文のコードをChatGPT(GPT-5.1)とGemini(Gemini 3。最初は思考モードで途中から高速モード)、Claude(Opus 4.5)の3つのLLMに見せて、「よりシンプルに書き直せますか?」と聞いてみました。彼らは正解例のコードを生成できたのでしょうか?



かわさき

 どうもHPかわさきです。

 突然に寒くなってきましたよね。そうなると、湯豆腐の季節だと思いませんか? 筆者は先日、京都まで湯豆腐を食べにいってきました。嵐山の方です。竹林の小道で熊に遭遇したらどうしようとドキドキしていたのですが、熊が割って入る隙がないくらいに人が多かったですねぇ。湯豆腐は大変おいしゅうございました。来年は南禅寺の方で湯豆腐を食べたいと思います(小学生の日記か)。お土産代わりに湯豆腐を一人で食べた写真を置いておきますね。

前に誰もいないので「匂わせ」ができない湯豆腐の写真 前に誰もいないので「匂わせ」ができない湯豆腐の写真


【答え】

  正解のコード例を以下に示します。

TEMPLATES = {
    'ja': 'こんにちは {name}さん',
    'es': 'Hola {name}',

    # 他にも各国語に対応した「テンプレート」がたくさん

    'en': 'Hello {name}',
}

def make_greeting(lang, name):
    template = TEMPLATES.get(lang, TEMPLATES['en'])
    return template.format(name=name)
        
greeting = make_greeting('ja', 'kawasaki')
print(greeting)  # こんにちは kawasakiさん

greeting = make_greeting('fr', 'kawasaki')
print(greeting)  # Hello kawasaki

言語コードをキーに、テンプレートとして使う文字列を値にした辞書とformatメソッドを組み合わせると関数本体はとてもシンプルになる

 ここではTEMPLATESという辞書を作成して、言語コードをそのキーに、名前を埋め込む対象の文字列をその値としています。この文字列はf文字列ではなく、単純な文字列ですが、置換フィールド「{name}」を持っています。make_greeting関数ではgetメソッドを使って言語コードに対応する文字列をTEMPLATESから取得します。そして、その文字列のformatメソッドで置換フィールドにnameの値を埋め込むことにしました。こうすることで、make_greeting関数がスッキリと書けるようになりました。

辞書とformatメソッドの組み合わせでスッキリ 辞書とformatメソッドの組み合わせでスッキリ

【解説】

 問題文のコードは次のようなものでした。

def make_greeting(lang, name):
    if lang == 'ja':
        return f'こんにちは {name}さん'
    elif lang == 'es':
        return f'Hola {name}'

        ...    # 他にもelif節がたくさん

    else:
        return f'Hello {name}'
        
greeting = make_greeting('ja', 'kawasaki')
print(greeting)  # こんにちは kawasakiさん

greeting = make_greeting('fr', 'kawasaki')
print(greeting)  # Hello kawasaki

文字列のformatメソッドを使って書き直してみよう

 このコードはシンプルで分かりやすいのですが、対応する言語コードが増えるとelif節の数もどんどん増えていくのが厄介です。そんなときには辞書を使うと、少しはコードがシンプルになります。f文字列を使ったまま、辞書バージョンのコードを書いてみましょう。

def make_greeting(lang, name):
    GREETINGS = {
        'ja': f'こんにちは {name}さん',
        'es': f'Hola {name}',

        # 他にも各国語に対応した挨拶文がたくさん

        'en': f'Hello {name}',
    }

    greeting = GREETINGS.get(lang, GREETINGS['en'])
    return greeting

greeting = make_greeting('ja', 'kawasaki')
print(greeting)  # こんにちは kawasakiさん

greeting = make_greeting('fr', 'kawasaki')
print(greeting)  # Hello kawasaki

辞書+f文字列のバージョン

 このバージョンでは、辞書の値をf文字列として関数が受け取ったnameをそこに埋め込んでいます。そして、getメソッドで言語コードに対応した「nameが埋め込まれた後」のf文字列を1つだけ取得して、それを戻り値にしています。

 このコードでもif文がなくなって、構造的にはスッキリしました。でも、関数呼び出しのたびにGREETINGSという辞書が作られて、その辞書の値でf文字列にnameの値が埋め込まれます。これってちょっと無駄じゃないですか? というのは、使われるf文字列は1つだけなのに、全ての言語のためにf文字列で文字列補完が行われるからです。

 それは関数の外に出せばいいじゃない? と思うかもしれません。こんな感じですね。

GREETINGS = {
    'ja': f'こんにちは {name}さん',
    'es': f'Hola {name}',

    # 他にも各国語に対応した挨拶文がたくさん

    'en': f'Hello {name}',
}

def make_greeting(lang, name):
    greeting = GREETINGS.get(lang, GREETINGS['en'])
    return greeting

f文字列はそれが評価される時点で補完要素がないとNameError例外となる

 でも、これはダメなのです。f文字列は評価される時点で埋め込むためのオブジェクトがなければ、NameError例外が発生してしまうからです。上の例ではnameが何かが分かりませんから、NameError例外が発生してしまうでしょう(手元で試したら発生しました)。

 このように「文字列をテンプレートとして、後からそこに何かを埋め込みたい」ときにはf文字列はあまりうまくありません。むしろ、正解例のコードで見せたように、単純な文字列をテンプレートとして、そのformatメソッドを使った方がよいでしょう。

TEMPLATES = {
    'ja': 'こんにちは {name}さん',
    'es': 'Hola {name}',

    # 他にも各国語に対応した「テンプレート」がたくさん

    'en': 'Hello {name}',
}

def make_greeting(lang, name):
    template = TEMPLATES.get(lang, TEMPLATES['en'])
    return template.format(name=name)
        
greeting = make_greeting('ja', 'kawasaki')
print(greeting)  # こんにちは kawasakiさん

greeting = make_greeting('fr', 'kawasaki')
print(greeting)  # Hello kawasaki

文字列をテンプレートとして、そのformatメソッドを使うことで無駄がなくなる

 これなら辞書の作成は関数外で一度だけで済みますし、必要のない文字列へのnameの値の埋め込みも行わずに済みます。最初はf文字列を使ったバージョンでもいいかなと思いましたが、そんなところを考慮するとformatメソッドを使うバージョンの方が無駄がないコードだと思います。といっても、筆者自身はどうかというと、普通に問題文のコードを書いちゃうわけですが……(笑)。まあ、f文字列が便利過ぎて、普段はついそれ任せにしてしまうのですが、そうでもない場合もあることを覚えておきましょう。

 なお、このようなif文を辞書(マップ)で置き換えることを「条件ロジックの辞書/マップでの置き換え」のように表現することもあり、リファクタリングではよくあるパターンともいえます。if文がかなり長くなってきたら「そんな方法もあったな」と思い出せるようにしておくとよいでしょう。


かわさき

 3つのLLMに「よりシンプルに書き直せますか?」と聞いて、最初に出てきたコードがどんなものだったのかを以下に列挙します。

  • ChatGPTさん:formatメソッドを使ったバージョン。ただし、辞書は関数内で定義
  • Geminiさん:formatメソッドを使ったバージョン。ただし、辞書は関数内で定義
  • Claudeさん:f文字列を値とする辞書を使ったバージョンとformatメソッドを使ったバージョンを提案して、前者を推奨

 3つのLLMにはあえて「formatメソッドを使って」という部分を省いて聞いてみました。それでも、3つのLLM全てがformatメソッドを使ったバージョンを生成してくれました。ただし、Claudeさんは同時にf文字列と辞書を使ったバージョンも生成して、そちらがイチオシとなっていました(その後、formatメソッドの方がよくない? と聞いたら同意してくれましたけど、LLMってそういうものよね)。例えば、以下はGeminiさんが生成してくれたコードです。

def make_greeting(lang, name):
    templates = {
        'ja': 'こんにちは {}さん',
        'es': 'Hola {}',
        # ここに 'fr': 'Bonjour {}' などを簡単に追加可能
    }
    
    fmt = templates.get(lang, 'Hello {}')
    return fmt.format(name)

Geminiさんが生成したコード

 置換フィールドに名前がないのですが、これはformatメソッドで埋め込む値が1つだけだからでしょう。複数あれば、きっと置換フィールドに名前を付けてくれたはず。

 気になるのは、3つのLLMの全てが辞書を外出しにはしてくれなかったところですかね(もちろん、外出しの方がよくない? と聞けば「鋭いご指摘ですね」と帰ってくるわけですが)。ま、これについても指摘をしたら、皆さん、その通りにしてくれました。

 というわけで、LLMは一発で最適な答えを出してくれるとは限らないってことが今回もよく分かりました(笑)。


「Pythonステップアップクイズ」のインデックス

Pythonステップアップクイズ

Copyright© Digital Advantage Corp. All Rights Reserved.

アイティメディアからのお知らせ

スポンサーからのお知らせPR

注目のテーマ

人に頼れない今こそ、本音で語るセキュリティ「モダナイズ」
4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。