Pythonの数値フォーマットは、f文字列の中でコロンの後ろに書式指定子を書く形(例:f"{n:05d}"、f"{n:,}"、f"{x:.2f}")が基本です。 同じ書式指定子は format() 関数と str.format() メソッドでもそのまま使え、文字列の0埋めには zfill が使えます。

この記事では、冒頭に「やりたいこと→書式指定子→出力」の早見表を置き、f文字列・format()・zfill の3通りを並べて比べます。そのうえで、:.2f や round で 2.675 が 2.67 になる理由と Decimal での対処、負数の0埋めで zfill と :05d がどう違うか、文字列に zfill を使う場面、f文字列の = 指定までを、すべて実行結果つきで説明します。

検証環境は Python 3.11.15 です。書式指定子の仕様は Python 3.14 の公式ドキュメント(書式指定ミニ言語、round 関数)でも確認しました。記事内のコードは、特に断りがない限り次の変数を使います。

n = 42
big = 1234567
x = 3.14159
r = 0.256

数値フォーマットの早見表

やりたいこと 書式指定子 f文字列 format() 出力
5桁で0埋め 05d f"{n:05d}" format(n, "05d") 00042
3桁ごとのカンマ区切り , f"{big:,}" format(big, ",") 1,234,567
3桁ごとのアンダースコア区切り _ f"{big:_}" format(big, "_") 1_234_567
小数点以下2桁 .2f f"{x:.2f}" format(x, ".2f") 3.14
パーセント表示(小数1桁) .1% f"{r:.1%}" format(r, ".1%") 25.6%
幅10で右寄せ >10 f"{n:>10}" format(n, ">10") 空白8個の後に 42
符号を必ず付ける + f"{n:+}" format(n, "+") +42
指数表記 e f"{big:e}" format(big, "e") 1.234567e+06
16進数 x f"{255:x}" format(255, "x") ff
カンマ区切り+小数2桁 ,.2f f"{v:,.2f}" format(v, ",.2f") 1,234,567.89
幅10で左寄せ <10 f"{n:<10}" format(n, "<10") 42 の後に空白8個
幅10で中央寄せ ^10 f"{n:^10}" format(n, "^10") 前後に空白4個ずつ
2進数を8桁0埋め 08b f"{255:08b}" format(255, "08b") 11111111

zfill は文字列のメソッドなので、0埋めの行だけ対応します。

やりたいこと zfill での書き方 出力
数値を5桁で0埋め str(n).zfill(5) 00042
文字列を3桁で0埋め "7".zfill(3) 007

早見表の実行結果です。

n = 42
big = 1234567
x = 3.14159
r = 0.256

print(f"{n:05d}", format(n, "05d"), str(n).zfill(5))
print(f"{big:,}", format(big, ","))
print(f"{big:_}", format(big, "_"))
print(f"{x:.2f}", format(x, ".2f"))
print(f"{r:.1%}", format(r, ".1%"))
print(f"[{n:>10}]", f"[{n:<10}]", f"[{n:^10}]")
print(f"{n:+}", f"{-n:+}")
print(f"{big:e}", f"{big:.2e}")
print(f"{255:x}", f"{255:X}", f"{255:#x}", f"{255:08b}")
print(f"{1234567.891:,.2f}")
00042 00042 00042
1,234,567 1,234,567
1_234_567 1_234_567
3.14 3.14
25.6% 25.6%
[        42] [42        ] [    42    ]
+42 -42
1.234567e+06 1.23e+06
ff FF 0xff 11111111
1,234,567.89

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python数値フォーマット早見表 0埋め・カンマ区切り・小数点桁数」

3つの書き方(f文字列・format()・zfill)の違い

書式指定子そのものは共通で、書く場所だけが違います。

書き方 例 特徴 向いている場面
f文字列 f"{n:05d}" 変数と書式を1か所に書ける。Python 3.6 以降 通常はこれを使う
format() 関数 format(n, "05d") 1つの値を整形して文字列で返す 値1つだけを整形、書式を変数で渡す
str.format() メソッド "{:05d}".format(n) テンプレート文字列を後から埋める 書式のテンプレートを別に持つ
zfill str(n).zfill(5) 文字列の左を0で埋める すでに文字列になっている値の0埋め
% 演算子 "%05d" % n 以前からある書き方 既存コードの読解

同じ結果になることを確かめます。

print(f"{n:05d} {big:,} {x:.2f} {r:.1%}")
print("{:05d} {:,} {:.2f} {:.1%}".format(n, big, x, r))
print(format(n, "05d"), format(big, ","), format(x, ".2f"), format(r, ".1%"))
print("{0:,} / {0:_} / {price:,}円".format(big, price=19800))
print("%05d|%8.2f|%+d|%x|%5.1f%%" % (n, x, n, 255, 25.6))
00042 1,234,567 3.14 25.6%
00042 1,234,567 3.14 25.6%
00042 1,234,567 3.14 25.6%
1,234,567 / 1_234_567 / 19,800円
00042|    3.14|+42|ff| 25.6%

% 演算子にはカンマ区切りの指定がありません。桁区切りを使うなら、f文字列か format を選びます。

書式指定子の並び順

書式指定子は、次の順番で必要なものだけを並べます。

[埋める文字][寄せ][符号][#][0][幅][桁区切り][.精度][型]
部分 書けるもの 意味
埋める文字 任意の1文字 幅が余ったときに埋める文字(寄せと一緒に書く)
寄せ < > ^ = 左寄せ、右寄せ、中央寄せ、符号の後ろを埋める
符号 + - 半角スペース 正の数にも符号を付ける、負だけ(既定)、正の数は空白
# # 2進数・8進数・16進数に 0b 0o 0x を付ける
0 0 符号を考慮した0埋め
幅 整数 全体の最小文字数
桁区切り , _ 3桁ごとの区切り
精度 .2 など 小数点以下の桁数(g では有効桁数)
型 d f e g % x b o c n 整数、固定小数点、指数、汎用、パーセント、16進数など

たとえば +010,.2f は「符号つき、0埋め、幅10、カンマ区切り、小数2桁、固定小数点」です。

print(f"{12345.6789:+010,.2f}")
+12,345.68

0埋め(ゼロパディング)をする

整数を0埋めする::05d

幅の前に 0 を書くと、足りない桁が0で埋まります。 幅より桁数が多い値は、そのまま出力されます。

print(f"{7:03d}", f"{42:05d}", f"{1234:03d}")
print(f"{5:02d}:{3:02d}:{9:02d}")
print(f"ID-{17:06d}")
print(f"{2026}-{3:02}-{7:02}")
007 00042 1234
05:03:09
ID-000017
2026-03-07

型の d は省略できます(:02 と :02d は整数では同じ結果)。整数であることをはっきり示したいときは d を付けておくと、文字列や小数を渡したときにエラーで気づけます。

小数を0埋めする::06.2f

小数の場合、幅には小数点と小数部も含まれます。

print(f"{3.5:06.2f}", f"{-3.5:07.2f}", f"{x:010.3f}")
003.50 -003.50 000003.142

06.2f は「全体で6文字、小数点以下2桁」です。003.50 は 0・0・3・ピリオド・5・0 の6文字になっています。

zfill で0埋めする

zfill は文字列のメソッドです。数値に対して使うときは、先に str で文字列にします。

print(str(42).zfill(5))
print("7".zfill(3), "12345".zfill(3), "".zfill(3))
print("A12".zfill(6))

try:
    (42).zfill(5)
except AttributeError as e:
    print(type(e).__name__, e)
00042
007 12345 000
000A12
AttributeError 'int' object has no attribute 'zfill'

負数の0埋め:zfill と :05d の違い

負数の0埋めは、書き方によって結果が変わるポイントです。

print(str(-42).zfill(5))     # zfill
print(f"{-42:05d}")          # 0 + 幅
print(f"{-42:0=5d}")         # = で「符号の後ろを埋める」と明示
print(f"{-42:0>5}")          # 0 を埋め文字にして右寄せ
print("-42".rjust(5, "0"))   # rjust
-0042
-0042
-0042
00-42
00-42
書き方 -42 を幅5で0埋め 符号の扱い
str(-42).zfill(5) -0042 符号を先頭に残して、その後ろを0で埋める
f"{-42:05d}" -0042 同上(符号を考慮した0埋め)
f"{-42:0=5d}" -0042 同上(05d はこの書き方の短縮形)
f"{-42:0>5}" 00-42 符号も1文字として扱い、単純に左を0で埋める
"-42".rjust(5, "0") 00-42 同上

zfill と :05d は、どちらも符号を先頭に残します。 結果が変わるのは 0>5 や rjust のように「0 という文字で右寄せする」書き方をした場合です。公式ドキュメントでも、幅の前の 0 は「埋め文字 0、寄せ =」と同じ意味だと説明されています。

では zfill と :05d の違いは何かというと、受け取れる型です。

print("+7".zfill(4), f"{7:+04d}")   # 符号つき
print(str(3.5).zfill(6))            # 小数の文字列にも使える

try:
    f"{'42':05d}"                   # 文字列に d は使えない
except ValueError as e:
    print(type(e).__name__, e)

print(f"{'42':0>5}", f"{int('42'):05d}", "42".zfill(5))
print(f"{'42':05}")                 # 文字列に 05 だけ書くと右側が埋まる
+007 +007
0003.5
ValueError Unknown format code 'd' for object of type 'str'
00042 00042 00042
42000
観点 zfill :05d
使える型 文字列(str) 整数(int)
数値にそのまま使えるか 使えない(str に変換が必要) 使える
文字列にそのまま使えるか 使える ValueError になる
負数・符号つき 符号の後ろを0で埋める 符号の後ろを0で埋める
英字まじりの文字列 左を0で埋める(000A12) 使えない
幅を超える値 そのまま返す そのまま出力

最後の f"{'42':05}" が 42000 になる点は見落としやすいところです。文字列は既定で左寄せのため、0 が右側に入ります(Python 3.10 以降の動作として公式ドキュメントに記載があります)。文字列を0埋めするときは zfill か :0>5 を使うと覚えておくと確実です。

文字列に zfill を使う場面

zfill が役立つのは、値がすでに文字列になっている場合です。CSV から読んだ番号、入力フォームの値、ファイル名の連番などが当てはまります。

ids = ["7", "42", "A-3", "1000"]
print([i.zfill(4) for i in ids])

# 文字列のまま並べ替えると、桁数が違う番号の順序が数値の順と変わる
print(sorted(["10", "9", "100"]))
print(sorted(x.zfill(3) for x in ["10", "9", "100"]))
print(sorted(["10", "9", "100"], key=int))

# 日付の各部分を2桁にそろえる
print("-".join(p.zfill(2) for p in "2026-3-7".split("-")))
['0007', '0042', '0A-3', '1000']
['10', '100', '9']
['009', '010', '100']
['9', '10', '100']
2026-03-07

桁をそろえておくと、文字列のままでも数値と同じ順に並びます。ファイル名に連番を付けるとき(img_001.png など)に0埋めをするのは、この並び順のためです。

状況 おすすめ
値が int で、文字列の中に埋め込む f"{n:05d}"
値が str(数字だけ、または英字まじり) s.zfill(5)
値が str で、数値として検証もしたい f"{int(s):05d}"
0 以外の文字で埋めたい s.rjust(5, "*") や f"{s:*>5}"

カンマ区切り・アンダースコア区切りにする

3桁ごとの区切り::, と :_

print(f"{big:,}", f"{big:_}")
print(f"{1234567.891:,.2f}", f"{1234567.891:_.2f}")
print(f"{-1234.5:+,.1f}")
print(f"{19800:,}円", f"¥{big:,}")
print(f"{123456789012345678:,}")
1,234,567 1_234_567
1,234,567.89 1_234_567.89
-1,234.5
19,800円 ¥1,234,567
123,456,789,012,345,678

小数の桁数と組み合わせるときは、カンマを先に、精度を後に書きます(,.2f)。順番を逆にするとエラーになります。

アンダースコア区切りは、Python のソースコードで数値を 1_000_000 と書ける記法と同じ見た目です。設定ファイルやログなど、後でプログラムに読み込ませる値に向いています。2進数や16進数では4桁ごとに入ります。

print(f"{0xFFFF:_x}", f"{0b11110000:_b}")
print(int("1_000"), int("1,234,567".replace(",", "")))
ffff 1111_0000
1000 1234567

カンマ入りの文字列を数値に戻すときは、replace でカンマを取り除いてから int に渡します。

幅・寄せと組み合わせる

表の形で数値を並べるときは、幅と右寄せを一緒に指定します。

print(f"{12345:>10,}|")
print(f"{12345:<10,}|")
print(f"{12345:^10,}|")
print(f"{12345:010,}")
    12,345|
12,345    |
  12,345  |
00,012,345

文字列にカンマ指定は使えない

try:
    f"{'1234567':,}"
except ValueError as e:
    print(type(e).__name__, e)

print(f"{int('1234567'):,}")
ValueError Cannot specify ',' with 's'.
1,234,567

CSV やフォームから受け取った値は文字列なので、int や float に変換してから書式を指定します。

小数点以下の桁数を指定する

固定の桁数::.2f

print(f"{x:.2f}", f"{x:.0f}", f"{3:.2f}", f"{3.0:.0f}")
print(f"{x:10.3f}|", f"{x:<10.3f}|")
print(f"{0.1 + 0.2}", f"{0.1 + 0.2:.2f}")
3.14 3 3.00 3
     3.142| 3.142     |
0.30000000000000004 0.30

.2f は常に小数点以下2桁で表示します。整数を渡しても 3.00 のように0が補われます。

有効桁数と指数表記::g と :e

print(f"{1234.5:g}", f"{0.00001234:g}", f"{123456789.0:g}", f"{1.50:.3g}")
print(f"{big:e}", f"{big:.2e}", f"{0.000012345:.3e}")
print(f"{1e-7}", f"{1e-7:.10f}", f"{1e16}", f"{1e16:.0f}")
1234.5 1.234e-05 1.23457e+08 1.5
1.234567e+06 1.23e+06 1.234e-05
1e-07 0.0000001000 1e+16 10000000000000000
型 意味 3.14159 の例
f 固定小数点(小数点以下の桁数を指定) .2f → 3.14
e 指数表記 .2e → 3.14e+00
g 有効桁数で、大きさに応じて f か e を自動選択 .3g → 3.14
% 100倍して % を付ける .1% → 314.2%

とても小さい値や大きい値は、書式を指定しないと 1e-07 のような指数表記になります。指数表記を避けたいときは f 型で桁数を明示します。

パーセント表示::.1%

% 型は、値を100倍してから % 記号を付けます。0.256 が 25.6% になります。

print(f"{r:.1%}", f"{r:.0%}", f"{1/3:.2%}", f"{1.5:%}")
print(f"{25:.1%}")            # すでに 25 という値を渡すと 2500.0% になる
print(f"{12.3456:.1f}%")      # すでにパーセントの値なら f 型 + 文字の %
25.6% 26% 33.33% 150.000000%
2500.0%
12.3%
元の値 書き方 出力
割合(0.256) f"{r:.1%}" 25.6%
すでにパーセントの数値(25.6) f"{v:.1f}%" 25.6%

:.2f と round の丸めに注意する

2.675 は 2.68 ではなく 2.67 になる

小数第3位が 5 の値を小数第2位に丸めると、四捨五入なら切り上がるはずです。実際に試します。

print(f"{2.675:.2f}", round(2.675, 2))
print(f"{2.665:.2f}", f"{2.685:.2f}")
print(f"{1.005:.2f}", round(1.005, 2))
2.67 2.67
2.67 2.69
1.00 1.0

2.675 は 2.67、2.665 は 2.67、2.685 は 2.69 と、切り上がるものと切り捨てられるものが混ざっています。理由は2つあります。

理由1:float は 2.675 をぴったり表せない。 コンピューターの小数(float)は2進数で値を持つため、多くの10進小数は「いちばん近い値」で保存されます。Decimal に渡すと、実際に保存されている値が見えます。

from decimal import Decimal

print(Decimal(2.675))
print(Decimal(1.005))
print(Decimal(0.125))
2.67499999999999982236431605997495353221893310546875
1.00499999999999989341858963598497211933135986328125
0.125

2.675 の実体は 2.67499… なので、小数第3位は 5 に届いておらず、2.67 に丸められます。公式ドキュメントの round の項にも、round(2.675, 2) が 2.67 になるのは不具合ではなく、多くの10進小数が float で正確に表せないためだ、という注記があります。

理由2:ちょうど真ん中の値は、偶数側に丸められる。 0.125 や 2.5 のように float でぴったり表せる値は、本当に「ちょうど真ん中」になります。このとき Python は、結果の末尾が偶数になる側を選びます(偶数丸め)。

print(round(0.5), round(1.5), round(2.5), round(3.5))
print(f"{0.5:.0f}", f"{1.5:.0f}", f"{2.5:.0f}")
print(f"{0.125:.2f}", f"{0.375:.2f}")
0 2 2 4
0 2 2
0.12 0.38
値 丸めた結果 説明
0.5 0 0 と 1 の真ん中 → 偶数の 0
1.5 2 1 と 2 の真ん中 → 偶数の 2
2.5 2 2 と 3 の真ん中 → 偶数の 2
3.5 4 3 と 4 の真ん中 → 偶数の 4
0.125 0.12 0.12 と 0.13 の真ん中 → 末尾が偶数の 0.12
0.375 0.38 0.37 と 0.38 の真ん中 → 末尾が偶数の 0.38
2.675 2.67 実体が 2.67499… なので、真ん中より小さい

偶数丸めは、たくさんの値を丸めて合計したときに、切り上げだけが積み重ならないようにするための方式です。:.2f と round は、どちらもこの同じ規則で丸めます。

Decimal で四捨五入する

学校で習う四捨五入(5 は常に切り上げ)にしたいときは、decimal モジュールの Decimal を使い、丸め方に ROUND_HALF_UP を指定します。

from decimal import Decimal, ROUND_HALF_UP

d = Decimal("2.675")                 # 文字列で渡す
print(d.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
print(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP))
print(Decimal("0.125").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
2.68
3
0.13

quantize の第1引数は「どの桁にそろえるか」の見本です。Decimal("0.01") なら小数第2位、Decimal("1") なら整数にそろえます。

ここで大切なのは、Decimal には文字列で値を渡すことです。float をそのまま渡すと、ずれた値がそのまま引き継がれます。

print(Decimal(2.675).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))       # float のまま
print(Decimal(str(2.675)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))  # str を経由
print(Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))     # 最初から文字列
2.67
2.68
2.68

float で受け取った値を四捨五入したい場合は、str を経由させる関数にしておくと使い回せます。

from decimal import Decimal, ROUND_HALF_UP

def round_half_up(value, ndigits=0):
    """四捨五入(5 は常に切り上げ)した Decimal を返す。"""
    unit = Decimal(1).scaleb(-ndigits)   # ndigits=2 なら 0.01
    return Decimal(str(value)).quantize(unit, rounding=ROUND_HALF_UP)

print(round_half_up(2.675, 2), round_half_up(0.125, 2))
print(round_half_up(2.5), round_half_up(-2.5))
print(f"{round_half_up(1234567.895, 2):,}")
2.68 0.13
3 -3
1,234,567.90

Decimal にも、カンマ区切りや小数桁の書式指定子がそのまま使えます。ただし、Decimal に .2f を指定したときの丸めは偶数丸めです。四捨五入にしたいときは、先に quantize で丸めてから書式を指定します。

print(f"{Decimal('2.665'):.2f}", f"{Decimal('2.675'):.2f}")
print(f"{Decimal('2.665').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP):.2f}")
print(f"{Decimal('19800') * Decimal('1.10'):,.0f}")
print(Decimal("0.1") + Decimal("0.2"), 0.1 + 0.2)
2.66 2.68
2.67
21,780
0.3 0.30000000000000004
目的 方法
画面表示用にだいたいの桁数へそろえる f"{x:.2f}"(偶数丸め、float の誤差あり)
四捨五入の結果を厳密にそろえたい Decimal(文字列).quantize(..., rounding=ROUND_HALF_UP)
計算の途中から誤差を持ち込みたくない 最初から Decimal で計算する

右寄せ・左寄せ・符号をそろえる

print(f"[{n:>10}]", f"[{n:<10}]", f"[{n:^10}]", f"[{n:*^10}]")
print(f"[{'abc':>10}]", f"[{'abc':10}]", f"[{n:10}]")
print(f"{n:+}", f"{-n:+}", f"{n: }", f"{0:+}")
print(f"{42:=+6}", f"{'abc':->8}")
[        42] [42        ] [    42    ] [****42****]
[       abc] [abc       ] [        42]
+42 -42  42 +0
+   42 -----abc

幅だけを指定した場合、数値は右寄せ、文字列は左寄せになります(2行目)。そろえ方を固定したいときは > や < を明示します。

幅や桁数を変数で指定する

書式指定子の中にも波かっこを書けます。

w = 8
p = 3
print(f"{x:{w}.{p}f}|")
print("{:{w}.{p}f}|".format(x, w=w, p=p))
print(f"{n:0{w}d}")
   3.142|
   3.142|
00000042

数値の列をそろえて表にする

rows = [("note", 120, 3), ("pen", 80, 12), ("file", 1500, 1000)]

print(f"{'name':<6}{'price':>7}{'qty':>6}{'total':>12}")
for name, price, qty in rows:
    print(f"{name:<6}{price:>7,}{qty:>6,}{price * qty:>12,}")
name    price   qty       total
note      120     3         360
pen        80    12         960
file    1,500 1,000   1,500,000

日本語(全角文字)を含む列は、文字数と表示幅が一致しないため、幅指定だけではそろいません。全角を2、半角を1として数える関数を用意し、足りない分の空白を自分で足します。

import unicodedata

def ljust_width(text, width):
    """全角を2、半角を1として左寄せする。"""
    w = sum(2 if unicodedata.east_asian_width(c) in "FWA" else 1 for c in text)
    return text + " " * (width - w)

for name, price in [("ノート", 120), ("ファイル", 1500)]:
    print(f"{ljust_width(name, 10)}{price:>7,}")
ノート        120
ファイル    1,500

2進数・8進数・16進数で表示する

print(f"{10:b}", f"{10:o}", f"{255:x}", f"{255:X}")
print(f"{10:#b}", f"{255:#x}", f"{255:#06x}", f"{255:#010b}")
print(f"{255:02X}", f"{10:08b}", f"{65:c}")
print(int("ff", 16), hex(255), bin(10))
1010 12 ff FF
0b1010 0xff 0x00ff 0b11111111
FF 00001010 A
255 0xff 0b1010

# を付けると 0x や 0b が先頭に付きます。# と0埋めを併用するときは、幅に接頭辞の2文字も含まれます(#06x は 0x00ff の6文字)。

f文字列の = 指定で、変数名と値を一緒に出す

Python 3.8 以降では、式の後ろに = を書くと「式=値」の形で出力されます。確認用の出力を手早く書けます。

total = 1234567
rate = 0.256
name = "備品"

print(f"{total=}")
print(f"{total=:,}")          # = の後ろに書式指定子を続けられる
print(f"{rate=:.1%}")
print(f"{total = }")          # = の前後の空白はそのまま出力される
print(f"{total * 2=}")        # 式もそのまま表示される
print(f"{name=}", f"{name=!s}")
print(f"{0.1 + 0.2=}", f"{0.1 + 0.2=:.2f}")
total=1234567
total=1,234,567
rate=25.6%
total = 1234567
total * 2=2469134
name='備品' name=備品
0.1 + 0.2=0.30000000000000004 0.1 + 0.2=0.30
書き方 出力 ポイント
f"{total=}" total=1234567 変数名と値
f"{total=:,}" total=1,234,567 書式指定子を続けて書ける
f"{total = }" total = 1234567 空白も再現される
f"{name=}" name='備品' 既定では repr 表示(文字列は引用符つき)
f"{name=!s}" name=備品 !s で str 表示にする

書式指定子を付けない場合は repr で表示されるため、文字列には引用符が付きます。書式指定子を付けた場合は、通常のフォーマットと同じ表示になります。

よくあるエラーと直し方

実際のエラー文を確かめます。

tests = [
    lambda: f"{'42':05d}",       # 文字列に d
    lambda: f"{3.7:05d}",        # 小数に d
    lambda: f"{42:.2d}",         # 整数に精度
    lambda: f"{'1234567':,}",    # 文字列にカンマ
    lambda: f"{None:05d}",       # None に書式
    lambda: (42).zfill(5),       # 数値に zfill
]
for t in tests:
    try:
        t()
    except Exception as e:
        print(type(e).__name__, e)
ValueError Unknown format code 'd' for object of type 'str'
ValueError Unknown format code 'd' for object of type 'float'
ValueError Precision not allowed in integer format specifier
ValueError Cannot specify ',' with 's'.
TypeError unsupported format string passed to NoneType.__format__
AttributeError 'int' object has no attribute 'zfill'
エラー・症状 原因 直し方
Unknown format code 'd' for object of type 'str' 文字列に d を指定した int(s) に変換する。または s.zfill(5)
Unknown format code 'd' for object of type 'float' 小数に d を指定した f 型にする。または int(v) に変換する
Precision not allowed in integer format specifier 整数の d に .2 を付けた .2f にする
Cannot specify ',' with 's'. 文字列にカンマ指定をした int(s) や float(s) に変換する
unsupported format string passed to NoneType.__format__ 値が None None のときの表示を先に決める(v if v is not None else 0 など)
'int' object has no attribute 'zfill' 数値に zfill を使った str(n).zfill(5) か f"{n:05d}"
0 が右側に入る(42000) 文字列に 05 を指定した zfill か :0>5 を使う
2500.0% のように100倍される パーセントの値に % 型を使った f"{v:.1f}%" にする
2.675 が 2.67 になる float の誤差と偶数丸め Decimal と ROUND_HALF_UP を使う
波かっこそのものを出したい 書式の開始と解釈される {{ と }} のように2つ重ねる

書く前のチェックリスト

  • 値の型は int・float・str・Decimal のどれか(文字列なら変換するか zfill を使う)
  • 0埋めの幅に、符号や小数点の文字数を含めて数えたか
  • カンマ区切りと小数桁を併用するなら ,.2f の順になっているか
  • パーセントは「割合の値」か「すでにパーセントの値」か
  • 丸めの規則(偶数丸めでよいか、四捨五入が必要か)を決めたか
  • 表示用の整形と、計算に使う値を分けているか(整形後は文字列になる)

よくある質問

Q. zfill と :05d はどちらを使えばよいですか? A. 値が数値(int)なら f"{n:05d}"、値がすでに文字列なら s.zfill(5) が向いています。負数ではどちらも -0042 のように符号の後ろを0で埋めます。f"{n:0>5}" や rjust は符号も1文字として左を埋めるため、00-42 になります。

Q. round(2.675, 2) が 2.68 にならないのはなぜですか? A. float の 2.675 は実際には 2.67499… という値で保存されているためです。さらに、0.125 のようにちょうど真ん中の値は偶数側に丸められます(0.12)。四捨五入にそろえたいときは、Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) のように Decimal を使います。

Q. カンマ区切りと小数点以下2桁を同時に指定するには? A. f"{value:,.2f}" と書きます。カンマ、ピリオドと桁数、型の順です。右寄せや幅も付けるなら f"{value:>15,.2f}" のように、寄せと幅をカンマの前に書きます。

Q. format() と f文字列はどちらを使うべきですか? A. Python 3.6 以降であれば、変数と書式を1か所に書ける f文字列が読みやすくおすすめです。書式のテンプレートを設定として別に持ちたい場合や、書式指定子を変数で受け取って1つの値を整形したい場合は、str.format() や format() 関数が向いています。書式指定子は共通なので、どちらで覚えてもそのまま応用できます。

まとめ

  • 数値フォーマットは f"{値:書式指定子}" が基本。同じ指定子が format() と str.format() でも使える
  • 0埋めは :05d、カンマ区切りは :,、小数桁は :.2f、パーセントは :.1%。組み合わせは ,.2f の順
  • zfill は文字列用、:05d は整数用。負数はどちらも -0042、:0>5 と rjust は 00-42
  • 文字列に 05 だけを指定すると右側が0で埋まる。文字列の0埋めは zfill を使う
  • :.2f と round は偶数丸め。2.675 は float の実体が 2.67499… のため 2.67 になる
  • 四捨五入は Decimal に文字列で渡し、ROUND_HALF_UP で quantize する
  • f"{total=:,}" のように = を付けると、変数名と整形した値を一緒に出せる

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python数値フォーマット早見表 0埋め・カンマ区切り・小数点桁数」

株式会社RJCでは、Pythonの数値フォーマットのような基本の書き方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?