閉じる

Pythonの文字列フォーマットまとめ(%演算子とformatメソッドの使い方)

コードやログの表示で読みやすさが大きく変わるため、Pythonでは文字列フォーマットがとても重要です。

本記事では昔ながらの2つの方法(パーセント演算子とstr.formatメソッド)に絞り、基礎から実践まで丁寧に解説します。

始めやすい書き方から幅や精度、整列、進数、エラー対処まで順を追って学べます。

Pythonの文字列フォーマットの基礎(%演算子とformatメソッド)

文字列フォーマットとは

文字列フォーマットとは、プレースホルダに値を差し込み、見やすく整形した文字列を作る仕組みです。

ログ出力、数値の丸め、表形式のレイアウトなど、日常のプログラミングで頻繁に登場します。

本記事では%演算子とstr.formatを扱います(f文字列は別記事で解説しています)。

    %演算子とformatメソッドの違い

    %演算子はC言語由来の古典的な書式で、短く書けてシンプルです。

    一方でformatメソッドは柔軟で、属性やキー参照、埋め文字や整列など拡張が豊富です。

    以下の観点で使い分けます。

    • 手短に整数や文字列を差し込むだけなら%が簡潔です。
    • 名前付きや再利用、複雑な整形が必要ならstr.formatが適します。
    • 国際化やテンプレート性を重視する場合はstr.formatのほうが表現力があります。

    フォーマット指定子の基本(幅・精度・整列)

    幅や精度、整列は出力の見やすさを左右します。

    両方式の代表的な指定は次のとおりです。

    目的%演算子formatメソッド
    幅(最小文字数)数字%10s数字{:10s}
    左寄せ-%-10s<{:<10s}
    右寄せ既定%10s>(既定){:>10s}
    中央寄せなし^{:^10s}
    0埋め0%06d0{:06d}
    精度(小数点/最大長).n%.2f.n{:.2f}
    符号+, %+d+, {:+d}

    精度は浮動小数点では小数点以下の桁数、文字列では最大文字数として機能します。

    %演算子の使い方

    基本形(%s,%d,%f)

    %sは文字列、%dは整数、%fは浮動小数点に使います。

    Python
    # 基本的な差し込み
    name = "Alice"
    age = 23
    score = 91.234
    
    print("Name: %s" % name)       # %s は任意のオブジェクトの文字列表現(str)を埋め込み
    print("Age: %d" % age)         # %d は整数
    print("Score: %f" % score)     # %f は浮動小数点(既定は小数点以下6桁)
    print("Score(小数2桁): %.2f" % score)
    実行結果
    Name: Alice
    Age: 23
    Score: 91.234000
    Score(小数2桁): 91.23

    複数値の埋め込み(タプル)

    複数値はタプルで渡します。

    Python
    user = ("Bob", 7)
    print("User: %s, ID: %d" % user)  # ("Bob", 7) が順に %s, %d に対応
    実行結果
    User: Bob, ID: 7

    名前付きプレースホルダ(%(name)s)

    辞書を渡して名前で参照できます。

    Python
    data = {"host": "localhost", "port": 5432}
    print("DB=%(host)s, PORT=%(port)d" % data)
    実行結果
    DB=localhost, PORT=5432

    幅・精度・0埋め・左寄せ

    幅は桁揃えに役立ちます。

    0埋めや左寄せも指定できます。

    Python
    n = 42
    pi = 3.14159
    s = "cat"
    
    print("[%10s]" % s)    # 右寄せ(幅10)
    print("[%-10s]" % s)   # 左寄せ(幅10)
    print("[%06d]" % n)    # 0埋め(幅6) -> 000042
    print("[%.3f]" % pi)   # 小数3桁に丸め
    print("[%.3s]" % "abcdef")  # 文字列を最大3文字に制限
    実行結果
    [       cat]
    [cat       ]
    [000042]
    [3.142]
    [abc]

    符号とスペース(+,-, )

    +は正数にも符号を表示し、 (スペース)は正数に空白を付けます。

    -は左寄せのフラグで符号指定ではありません

    Python
    print("[%+d] [% d] [%d]" % (7, 7, -7))
    実行結果
    [+7] [ 7] [-7]

    リテラルの%を出す(%%)

    パーセント記号自体を表示するには%%を使います。

    Python
    rate = 0.375
    print("Progress: %.1f%%" % (rate * 100))
    実行結果
    Progress: 37.5%

    %rと%sの違い

    %sはstr()、%rはrepr()を使います。

    デバッグには%rが有用です。

    Python
    text = 'He said "hi".'
    none_val = None
    print("%s | %r" % (text, text))        # %r はクォートやエスケープを可視化
    print("%s | %r" % (none_val, none_val))  # None の表示比較
    実行結果
    He said "hi". | 'He said "hi".'
    None | None

    数値書式(指数%e,16進%x)

    指数表記や進数表記も可能です。

    Python
    num = 12345.6789
    value = 255
    print("exp: %e" % num)   # 指数(小文字)
    print("EXP: %E" % num)   # 指数(大文字)
    print("hex: %x" % value) # 16進(小文字)
    print("HEX: %X" % value) # 16進(大文字)
    実行結果
    exp: 1.234568e+04
    EXP: 1.234568E+04
    hex: ff
    HEX: FF

    formatメソッドの使い方

    基本形({}とstr.format)

    中括弧{}がプレースホルダです。

    型を自動判定して文字列化します。

    Python
    msg = "Hello, {}. You have {} new messages.".format("Alice", 3)
    print(msg)
    実行結果
    Hello, Alice. You have 3 new messages.

    位置引数と名前付き引数

    位置や名前を明示できます。

    自動番号と明示番号は混在不可です。

    Python
    print("{0} scored {1}".format("Bob", 92))                 # 位置引数を番号で参照
    print("{name} scored {score}".format(name="Eve", score=88))  # 名前付き引数
    # print("{} {1}".format("X", "Y"))  # 混在はエラー(ValueError)
    実行結果
    Bob scored 92
    Eve scored 88

    フィールド名の参照(属性・キー・インデックス)

    ドットで属性[]でキー/インデックスを参照できます。

    Python
    class User:
        def __init__(self, name): self.name = name
    
    u = User("Kai")
    data = {"x": 10, "y": 20}
    arr = ["zero", "one"]
    
    print("user={0.name}".format(u))          # 属性
    print("point=({p[x]}, {p[y]})".format(p=data))  # 辞書キー
    print("arr[1]={a[1]}".format(a=arr))      # リストのインデックス
    実行結果
    user=Kai
    point=(10, 20)
    arr[1]=one

    書式指定ミニ言語(:指定子)の基本

    コロン:に続けてミニ言語で詳細指定を行います。

    • 形: {フィールド:埋め文字整列幅.精度型}
    • 例: {:>10s}(右寄せ幅10)、{:.2f}(小数2桁)

    整列記号は<(左)、>(右)、^(中央)です。

    Python
    x = 3.14159
    print("[{:10}]".format("cat"))   # 既定は右寄せ
    print("[{:<10}]".format("cat"))  # 左寄せ
    print("[{:^10}]".format("cat"))  # 中央寄せ
    print("{:.3f}".format(x))        # 小数3桁
    実行結果
    [       cat]
    [cat       ]
    [   cat    ]
    3.142

    文字列の整列と幅・埋め文字(<,>,^)

    任意の1文字を埋め文字にできます。

    Python
    print("[{:*>8}]".format("42"))   # '*'で右側に詰めて左を埋める
    print("[{:_^8}]".format("OK"))   # '_'で中央寄せの両側を埋める
    実行結果
    [******42]
    [___OK___]

    数値の精度・符号・0埋め

    符号や0埋めは読みやすさに直結します。

    Python
    n = 42
    neg = -42
    pi = 3.14159
    
    print("{:+d}".format(n))     # 正数にも+を表示
    print("{: d}".format(n))     # 正数は先頭に空白
    print("{:06d}".format(n))    # 0埋め(幅6)
    print("{:.2f}".format(pi))   # 小数2桁
    print("{:+.2f}".format(pi))  # 小数2桁かつ符号
    print("{: .2f}".format(neg)) # 符号と空白(負はマイナス表示)
    実行結果
    +42
     42
    000042
    3.14
    +3.14
    -42.00

    千区切り(,)とパーセント(%)

    千区切り,百分率%も組み込みです。

    百分率は値を100倍して%を付けます。

    Python
    num = 1234567.89
    ratio = 0.375
    print("{:,}".format(num))         # 1,234,567.89
    print("{:.2%}".format(ratio))     # 37.50%
    実行結果
    1,234,567.89
    37.50%

    進数変換(b,o,d,x,X)と指数(e,E)

    2進や16進、指数表記が簡単です。

    Python
    v = 255
    x = 12345.6789
    print("{:b}".format(v))  # 2進
    print("{:o}".format(v))  # 8進
    print("{:d}".format(v))  # 10進
    print("{:x}".format(v))  # 16進(小文字)
    print("{:X}".format(v))  # 16進(大文字)
    print("{:e}".format(x))  # 指数(小文字)
    print("{:E}".format(x))  # 指数(大文字)
    実行結果
    11111111
    377
    255
    ff
    FF
    1.234568e+04
    1.234568E+04

    ネストと再利用(番号・名前)

    同じ値を何度も使ったり、精度を動的に指定できます。

    Python
    name = "Mio"
    pi = 3.14159265
    
    # 同じ値の再利用
    print("Hi {0}, again {0}!".format(name))
    
    # 動的精度のネスト: {0:.{p}f} の p は名前付き引数
    print("PI={0:.{p}f}".format(pi, p=4))
    実行結果
    Hi Mio, again Mio!
    PI=3.1416

    選び方と注意点(%演算子 vs formatメソッド)

    どちらを使うべきかの目安

    短く済ませたい単純置換は%、柔軟な整形や再利用・名前参照はformatが向きます。

    既存コードの流儀に合わせるのも実務で大切です。

    よくあるエラー(TypeError,KeyError,ValueError)

    指定子やフィールド名の不一致で例外が出ます。

    以下は代表例です。

    Python
    def show_error(fn):
        try:
            fn()
        except Exception as e:
            print(type(e).__name__, "-", e)
    
    # 1) % 演算子: 指定子と値の不一致
    show_error(lambda: print("%d" % "42"))  # 文字列に %d は不可 -> TypeError
    
    # 2) format: 存在しない名前
    show_error(lambda: print("{name}".format(user="Ann")))  # name が無い -> KeyError
    
    # 3) format: 自動番号と明示番号の混在
    show_error(lambda: print("{} {1}".format("A", "B")))  # -> ValueError
    実行結果
    TypeError - %d format: a number is required, not str
    KeyError - 'name'
    ValueError - cannot switch from automatic field numbering to manual field specification

    型と指定子の不一致に注意

    数値型に文字列指定子、文字列に数値指定子を使うとエラーです。

    例えば%d{:d}は整数専用、{:.2f}は数値専用です。

    安全側に倒すなら%s{}で受け、必要に応じて明示的にint()float()に変換します。

    Python
    s = "100"
    # 明示変換してから数値書式を使う
    print("{:05d}".format(int(s)))
    print("%.2f" % float(s))
    実行結果
    00100
    100.00

    可読性・メンテ性の比較

    長い文や多くの値を差し込む場合、名前付きのformatは意図が読み取りやすいです。

    翻訳対応でも並び順変更に強くなります。

    Python
    # 名前付きで意味が明確
    tpl = "User={name}, Role={role}, Active={active}"
    print(tpl.format(name="Aya", role="admin", active=True))
    実行結果
    User=Aya, Role=admin, Active=True

    パフォーマンスと互換性の観点

    どちらもPython 3で広く使え、互換性に問題はありません

    性能差はケース依存で、I/O付近では誤差程度です。

    可読性と保守性を優先し、既存コードのスタイルに合わせるのが現実的です。

    大量連結が必要なら、そもそもjoinやバッファリングを検討します。

    まとめ

    パーセント演算子はシンプルで短く、formatメソッドは柔軟で表現力が高いという住み分けを押さえれば、状況に応じた最適なフォーマットが選べます。

    幅や精度、整列、符号、0埋め、進数、千区切り、百分率などを必要に応じて使い分け、エラーになりやすい型と指定子の不一致に注意してください。

    最終的にはプロジェクトの方針と可読性を基準に、一貫した書き方で整った出力を心がけると保守性が高まります。

    この記事を書いた人
    エーテリア編集部
    エーテリア編集部

    人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

    クラウドSSLサイトシールは安心の証です。

    URLをコピーしました!