閉じる

【Python】 f-string(f文字列)の使い方: 基本から書式指定子まで

Pythonのf-string(f文字列)は、可読性と実用性を両立した現代的な文字列フォーマット機能です。

変数や式を{}に直接書けるため、文字列連結やformat()に比べて短く読みやすいコードになります

本記事では基本から書式指定子、数値や日付の整形、応用テクニック、注意点までを段階的に解説します。

f-string(f文字列)の基本

f-stringとは(Python 3.6+)

f-stringはPython 3.6で導入された文字列リテラルで、冒頭にfまたはFを付け、文字列中の{}内にPythonの式を直接書けます。

評価結果がその場で埋め込まれるため、簡潔で読みやすいコードになります。

Python
# f-stringの最小例
name = "Alice"
age = 20
msg = f"名前は{name}、年齢は{age}です"
print(msg)
実行結果
名前はAlice、年齢は20です

基本構文(f”…{式}…”)

f"…{式}…"の形で、{}の中に有効なPython式を書けます。

変数名だけでなく、四則演算や関数呼び出しなども使えます。

Python
# {} の中は式を書ける
a, b = 7, 3
print(f"{a} + {b} = {a + b}")         # 式(加算)
print(f"平方は {b**2}")               # べき乗
print(f"長さは {len('hello')}")       # 関数呼び出し
実行結果
7 + 3 = 10
平方は 9
長さは 5

変数と式の埋め込み

f-stringではstr()への明示的な変換が不要です。

複数の変数を自然に混在できます。

Python
# 変数・式をそのまま埋め込む
user = "bob"
items = ["pen", "notebook"]
count = len(items)
print(f"{user}さんのアイテム数は{count}個({items})です")
実行結果
bobさんのアイテム数は2個(['pen', 'notebook'])です

文字列と数値をそのまま結合

従来の"Hi " + name + " #" + str(n)のような書き方は不要です。

数値も{}に入れれば自動で文字列化されます。

Python
name, n = "Carol", 42
print(f"Hi {name} #{n}")
実行結果
Hi Carol #42

デバッグ出力(=)の使い方(Python 3.8+)

Python 3.8以降、{式=}式と結果をペアで表示できます。

結果はrepr()で表現されます。

Python
# デバッグに便利な = 指定子 (Python 3.8+)
path = "/usr/local/bin"
n = 5
print(f"{path=}, {n=}, {n*2=}")
実行結果
path='/usr/local/bin', n=5, n*2=10

変換フラグ(!s !r !a)の違い

!sstr()!rrepr()!aascii()で表示へ変換します。

デバッグには!rが役立ちます。

Python
# 変換フラグの例
text = "こんにちは\n"  # 改行を含む
print(f"デフォルト: {text}")
print(f"!s: {text!s}")
print(f"!r: {text!r}")  # エスケープを含む表現
print(f"!a: {'αβ'!a}")   # 非ASCIIを\x, \u などで表現
実行結果
デフォルト: こんにちは

!s: こんにちは

!r: 'こんにちは\n'
!a: '\u03b1\u03b2'

波かっこを出力する({{ }})方法

文字通りの{/}を出力したい場合は二重の波かっこを使います。

Python
# { と } を文字として出す
print(f"ブレースは {{ と }} です")
実行結果
ブレースは { と } です

書式指定子(:)の基礎

書式の書き方({値:指定})

{値:指定}の形で整形ルールを与えます。

書式指定の構成は概ね次の順序です。

要素意味
[fill][align]埋め文字と配置_>10で右寄せを<em>_</em>で埋め
[sign]符号+, -, 空白
[#]代替形式基数接頭辞0xなど
[0]数値のゼロ埋め08
[width]10
[grouping]桁区切り, または _
[.precision]精度.2
[type]d, f, x, % など
Python
# フォーマット指定の基本
x = 1234.5678
print(f"[{x:10.2f}]")   # 幅10, 小数2桁
print(f"[{x:>10.2f}]")  # 右寄せ
print(f"[{x:^10.2f}]")  # 中央寄せ
実行結果
[   1234.57]
[   1234.57]
[ 1234.57 ]

幅と配置(< > ^)で揃える

表形式の出力で整列に使います。

<(左寄せ)、>(右寄せ)、^(中央寄せ)です。

Python
# 幅と配置
headers = ("item", "qty", "price")
rows = [("apple", 3, 120), ("banana", 10, 58), ("kiwi", 1, 240)]
print(f"{headers[0]:<10} {headers[1]:>5} {headers[2]:>8}")
for name, qty, price in rows:
    print(f"{name:<10} {qty:>5d} {price:>8d}")
実行結果
item             qty    price
apple              3      120
banana            10       58
kiwi               1      240

埋め文字とゼロ埋め(0)

任意の1文字で埋められます。

数値の左側を0で埋めるには0を使います。

Python
# 埋め文字とゼロ埋め
n = 42
print(f"[{n:_>6}]")   # '_'で右側に埋め
print(f"[{n:*^6}]")   # '*'で中央寄せ
print(f"[{n:06}]")    # 0埋め(幅6)
実行結果
[____42]
[**42**]
[000042]

精度(.n)と丸め

小数の桁数を指定します。

fなら小数点以下の桁数、gなら有効桁数です。

Python
# 精度の指定
x = 1/3
print(f"{x:.2f}")  # 2桁に丸め
print(f"{x:.5f}")  # 5桁に丸め
print(f"{12345.6789:.3g}")  # 有効桁数3
実行結果
0.33
0.33333
1.23e+04

符号(+ – space)の制御

+は正数にも+を付け、-は負数のみ符号、空白は正数にスペースを付けます。

Python
p, n = 12, -12
print(f"{p:+d}, {n:+d}")  # +12, -12
print(f"{p: d}, {n: d}")  #  12, -12
print(f"{p:-d}, {n:-d}")  # 12, -12 (デフォルト)
実行結果
+12, -12
 12, -12
12, -12

桁区切り(,)の指定

,で3桁ごとの区切りが入ります。

_でアンダースコア区切りも可能です。

Python
# 桁区切り
m = 1234567890
print(f"{m:,}")   # カンマ
print(f"{m:_}")   # アンダースコア
実行結果
1,234,567,890
1_234_567_890

大文字小文字の指定

16進や指数表記は大文字/小文字を選べます。

x/Xe/Eg/Gなどです。

Python
# 大文字/小文字指定
n = 48879
print(f"{n:x}")  # 16進(小文字)
print(f"{n:X}")  # 16進(大文字)
y = 12345.678
print(f"{y:e}")  # 指数(小文字e)
print(f"{y:E}")  # 指数(大文字E)
実行結果
beef
BEEF
1.234568e+04
1.234568E+04

数値と日付のフォーマット

整数の基数(b o x X)

2進b、8進o、16進x/Xに対応します。

#接頭辞(例:0x)を付けられます。

Python
# 整数の基数
n = 255
print(f"{n:b}")     # 2進
print(f"{n:o}")     # 8進
print(f"{n:x}")     # 16進(小)
print(f"{n:#x}")    # 0x接頭辞あり
print(f"{n:#X}")    # 0X接頭辞あり
実行結果
11111111
377
ff
0xff
0XFF

小数と科学表記(f e E g)

固定小数点f、指数表記e/E、状況に応じて最適なg/Gがあります。

Python
# 浮動小数の表記
x = 1234.56789
print(f"{x:.2f}")  # 2桁固定
print(f"{x:.3e}")  # 指数表記
print(f"{x:.6g}")  # 有効桁数6
実行結果
1234.57
1.235e+03
1234.57

パーセント(%)表示

%を使うと自動で100倍して%が付きます。

Python
# パーセント表記
rate = 0.12345
print(f"{rate:.1%}")  # 小数1桁の百分率
print(f"{rate:.2%}")  # 小数2桁
実行結果
12.3%
12.35%

通貨風フォーマットのコツ

簡単にはf"¥{amount:,}"のように記述します。

負数や括弧表記などが必要なら規則を自作するかlocaleや外部ライブラリを使います。

Python
# シンプルな通貨風表示
amounts = [1200, 9876543, -350]
for a in amounts:
    sign = "-" if a < 0 else ""
    print(f"{sign}¥{abs(a):,}")
実行結果
¥1,200
¥9,876,543
-¥350
Python
# localeを使った例(環境に依存します)
import locale
locale.setlocale(locale.LC_ALL, "ja_JP.UTF-8")  # 環境にこのロケールが必要
n = 1234567.8
print(locale.currency(n, grouping=True))  # 例: '¥1,234,567.80'
実行結果
¥1,234,568

日付時刻の書式(datetimeの%記法)

datetimeは__format__を実装しており、f"{dt:%Y-%m-%d %H:%M}"のようにstrftime互換の記法が使えます。

Python
# 日付をf-stringで整形
from datetime import datetime
dt = datetime(2024, 5, 1, 14, 30, 5)
print(f"{dt:%Y-%m-%d %H:%M:%S}")   # 2024-05-01 14:30:05
print(f"{dt:%Y年%m月%d日(%a) %H時%M分}")  # ローカライズは環境に依存
実行結果
2024-05-01 14:30:05
2024年05月01日(Wed) 14時30分

応用テクニックと注意点

条件式や関数呼び出しを埋め込む

{}の中には条件演算子も書けます。

ただし、複雑になりすぎる場合は事前に変数へ代入して可読性を保ちます。

Python
# 三項演算子や関数呼び出し
score = 78
def rank(s):
    return "A" if s >= 80 else "B" if s >= 65 else "C"

print(f"点数:{score} 評価:{rank(score)} "
      f"合否:{'合格' if score >= 60 else '不合格'}")
実行結果
点数:78 評価:B 合否:合格

dictやlistのキー/インデックス参照

辞書やリストへのアクセスも記述できます。

キーの引用符に注意します。

Python
# dict, list 参照
user = {"name": "Alice", "age": 30}
nums = [10, 20, 30]
print(f"{user['name']}さんは{user['age']}歳です。最初の数は{nums[0]}です")
実行結果
Aliceさんは30歳です。最初の数は10です

ネストしたフォーマット指定

幅や精度を変数で動的に指定できます。

入れ子の{}でパラメータを渡すイメージです。

Python
# 動的な幅や精度
pi = 3.1415926535
w, p = 8, 4
print(f"[{pi:{w}.{p}f}]")   # 幅w, 小数p桁
n = 255
base = "X"  # 'x' or 'X'
print(f"{n:#{base}}")       # 0x/0X付きで16進
実行結果
[  3.1416]
0XFF

複数行f-stringとインデント

三重引用符で複数行を扱えます。

インデントを取り除きたい場合はtextwrap.dedentが便利です。

Python
# 複数行のf-string
from textwrap import dedent
user = "Bob"
items = ["pen", "notebook"]
block = f"""
    ユーザー: {user}
    点数: {sum([40, 30])}
    アイテム: {", ".join(items)}
"""
print(dedent(block).strip())
実行結果
ユーザー: Bob
点数: 70
アイテム: pen, notebook

fr”…”の注意点(生文字列との併用)

fとrは併用可能です(fr"..."rf"...")。

ただし生文字列はバックスラッシュを解釈しない一方、{}内の式は通常通り評価されます。

行末のバックスラッシュや一部のエスケープは注意が必要です。

Python
# fr文字列の例
path = r"C:\Users\name"
pat  = r"\d+"
print(fr"Path={path}, Regex={pat}, テスト={'\n'.join(['A','B'])!r}")
実行結果
Path=C:\Users\name, Regex=\d+, テスト='A\nB'

パフォーマンスと可読性

一般にf-stringはformat()%より高速です。

とはいえ、最優先は可読性で、過剰な入れ子や長大な式は避けるべきです。

必要に応じて事前に変数へ分解しましょう。

Python
# 参考: 簡易ベンチマーク(結果は環境で変わります)
import timeit
print("f-string:", timeit.timeit("name='A'; n=1; f'{name} {n}'", number=1_000_000))
print("format():", timeit.timeit("name='A'; n=1; '{} {}'.format(name,n)", number=1_000_000))
print("%演算子  :", timeit.timeit("name='A'; n=1; '%s %d' % (name,n)", number=1_000_000))
実行結果
f-string: 0.20
format(): 0.34
%演算子  : 0.26

セキュリティの注意(外部入力を式にしない)

外部入力を式として{}に評価する設計は危険です。

f-stringはソースコードに書かれた式を評価しますが、動的に式文字列を組み立ててeval()するのは避けましょう。

また、SQLやシェルへは必ずプレースホルダや安全なAPIを使います。

Python
# 悪い例: 入力をevalで評価しない
# good例: SQLはパラメータ化する
import sqlite3
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE t(id INT, name TEXT)")
name = "Alice'); DROP TABLE t; --"
cur.execute("INSERT INTO t VALUES (?, ?)", (1, name))  # 安全なプレースホルダ
conn.commit()
print("OK")
実行結果
OK

バージョン互換性(Python 3.6+/=は3.8+)

f-string自体はPython 3.6+、デバッグ用の{expr=}3.8+です。

古い環境を対象にする場合は注意してください。

機能対応バージョン
f-string本体Python 3.6+
デバッグ表示{x=}Python 3.8+
桁区切り_指定Python 3.6+

まとめ

f-stringは読みやすさ、書きやすさ、速度のバランスに優れた文字列整形手段です。

基本のf"…{式}…"で変数や式をシンプルに埋め込み、書式指定子で見た目を整え、数値や日付の定番パターンを覚えると多くの用途をカバーできます。

複雑なロジックは事前に変数へ分け、外部入力を式として評価しないという安全策を守れば、保守性と安全性の高いコードを書けます。

日常の出力からログ、レポート生成まで、まずはf-stringを標準の選択肢として活用してみてください。

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

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

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

URLをコピーしました!