概要
いい感じのPython文字列フォーマット一覧がどれだけ探しても見つからないので自分でまとめました。
サンプルは原則としてf-stringを利用していますので、Python3.6以降を使用している方は読みやすいかもしれません。
サンプルの動作確認はすべて Python3.8.6 において行っています。
一部これ以降のバージョンに関する記述がありますが、それらはすべて公式のドキュメントに拠ったものです。
Pythonの書式指定についてもっと詳しく知りたい方は こちら のドキュメントをご覧ください。
書式指定のキホン
書式指定を行うメソッド
書式指定を利用するには format()
、 str.format()
、 f-string
、 % 書式
のいずれかを使います。図でサクッと4つを比較してみましょう。
メソッドの使い方(ざっくりと文字説明)
format()
は次のように第1引数に 値 、第2引数に 書式を指定する特別な文字列(後述) を設定します。
format(値, 書式指定) # -> str
str.format()
は文字列中の {}
を 置換フィールド(プレースホルダー)とみなし、引数に設定した値をフォーマットして埋め込みます。書式指定は {}
内に :
を伴って行います。値は文字列リテラルの {}
内でなくメソッドの引数に与えます。
"{:書式指定}".format(値) # -> str
f-string
(フォーマット済み文字列リテラル)は、従来の文字列リテラル ""
に str.format()
の考え方を組み込んだ、より簡潔な記述を可能にした文字列リテラルです。Python3.6で登場しました。
f"{値:書式指定}" # -> str
ほかにも C でいうところの printf()
のように使用できる % 書式
を用いた記法も用意されています。
こちらの説明に関しましては、可読性の面から「できるだけ f-string
か str.format()
を使ってほしい!」という思いを込めまして割愛いたします。ちなみに こちら の記事によりますと速度は一般にもっとも速いようです。
2020-03-13 :
str.format()
と% 書式
の不足についてコメントでご指摘いただきましたので追記いたしました。
書式指定の文法
「書式指定の方法と種類だけ知りたい!」という方はこの節は飛ばしていただいて構いません。
ですが「Pythonの書式指定をマスターしたい!」という方にはぜひご一読いただきたい内容になっています。
f-stringが説明の中心になります。
ドキュメントでは書式指定の文法構造について次のように表現されています。
図からも分かるように、書式指定は「フィールド」と呼ばれる field_name
conversion
format_spec
の3要素で構成されています。それぞれの持つ役割は次の通りです。
-
field_name
(必須)
書式指定を行う対象オブジェクトを指定します。
必ず置換フィールドの先頭に配置します。 -
conversion
(任意)
field_name
に与えられたオブジェクトを文字列として埋め込む上で、最初に行う基礎的な変換を指定します。!
を先頭に伴います。
オブジェクト指向を採用しているPythonにおいて、オブジェクトの文字列化に期待されるものがただ一つであるとは限りません。この問題を解決するためにPythonではクラスに特殊メソッドの定義を可能にすることで対応できるようにしています。
このフィールドに指定することによって機能するのは上に記した通り一部の特殊メソッドであり、このフィールドに指定できる文字は Python3.10 現在でs
r
a
の3つです。これらは以下に示す特殊メソッドに紐づいています。処理によって返されたstr
が後のformat_spec
での処理に与えられます。
オプション | 対応するメソッド | 等価のメソッド |
---|---|---|
s |
__str__() |
str() |
r |
__repr__() |
repr() |
a |
__ascii__() |
ascii() |
なお、conversion
を指定した場合の返り値は必ず str
となりますから、format_spec
フィールドに指定可能な指定子のうち多くが適用不可になる点について注意が必要です。
print(f"{str(obj)}")
print(f"{obj!s}")
print(f"{obj}") # f-string はデフォルトで !s を選択します
print(f"{repr(obj)}")
print(f"{obj!r}")
print(f"{ascii(obj)}")
print(f"{obj!a}")
-
format_spec
(任意)
「field_name
フィールドに指定したオブジェクトそのもの」か、「conversion
フィールドの指定によって変換された文字列」の書式指定を行います。:
を先頭に伴います。これを用いた書式指定に関してはそれぞれについて後に詳しく説明しています。
配置
自動設定(width)
指定した幅の中でそれぞれの型ごとに自動で最適な配置を行います。
print(f"'{123:10}'") # int
print(f"'{123.45:10}'") # float
print(f"'{'hoge':10}'") # str
print(f"'{True:10}'") # bool
print(f"'{False:10}'") # bool
' 123' # int
' 123.45' # float
'hoge ' # str
' 1' # bool(True)
' 0' # bool(False)
なお、None
が与えられた場合は TypeError が発生します。
print(f"'{None:10}'") # None
# TypeError: unsupported format string passed to NoneType.__format__
任意設定(align)
記号(<, ^, >)で配置を指定して直後に確保する字数を指定します。
a = "hoge"
print(f"'{a:<10}'") # 左寄せ
print(f"'{a:^10}'") # 中央寄せ
print(f"'{a:>10}'") # 右寄せ
'hoge ' # 左寄せ
' hoge ' # 中央寄せ
' hoge' # 右寄せ
なお、中央揃えにおいて左右の余白が一致しない場合は左に寄せられます。
a = "hoge" # 偶数文字
b = "abcde" # 奇数文字
print(f"a = '{a:^10}'") # 偶数余白に対して偶数文字
print(f"b = '{b:^10}'") # 偶数余白に対して奇数文字
' hoge ' # 中央
' abcde ' # 中央より少し左
余白を文字埋め(fill)
余白をスペース以外で表す(文字埋めする)場合、次のように1文字を指定し文字埋めすることが可能です。
0埋めを行いたい場合は特別なオプションが用意されていますので、これの詳細については後述します。
print(f"'{a:.<20}'") # 左寄せ(ドット埋め)
print(f"'{a:.^20}'") # 中央寄せ(ドット埋め)
print(f"'{a:.>20}'") # 右寄せ(ドット埋め)
# 'hoge................'
# '........hoge........'
# '................hoge'
数値の書式
桁数指定(.precision)
小数の精度を指定できます。
c = 1234.5678
print(f"c = {c:.2f}") # 小数第2位まで(小数第3位を四捨五入)
print(f"c = {c:10.2f}") # 10文字確保して小数第2位まで
# c = 1234.57
# c = 1234.57
なお、小数点以下の余白については自動的に0埋めされます。
一部のPython情報サイトで「 小数点以下の0埋めは .
の直後に 0
を付して指定する」旨の記述がみられましたが、比較してみると等価であるようです。
print(f"c = {c:.8f}") # 小数点以下に確保した文字幅が小数点以下の桁数を上回った場合
print(f"c = {c:.08f}") # 一部のサイトで解説されていた小数点以下0埋めの指定方法
# c = 1234.56780000
# c = 1234.56780000
3桁区切り(grouping_option)
d = 123456789
print(f"d = {d:,}") # カンマ
print(f"d = {d:_}") # アンダースコア
# d = 123,456,789
# d = 123_456_789
正負符号(sign)
e = 123
f = -456
print(f"e = {e:+}") # 正負の値それぞれでプラスかマイナスを付す。
print(f"f = {f:+}")
print(f"e = {e:-}") # 負の値のみマイナスを付す。(デフォルトの挙動)
print(f"f = {f:-}")
print(f"e = {e: }") # 正の値のとき1マスを余分に確保して桁を揃える。
print(f"f = {f: }")
# e = +123
# f = -456
# e = 123
# f = -456
# e = 123
# f = -456
符号と値の間の文字埋め(fill, align)
=
を使用することで符号と値の間に空白がある場合に限り文字埋めが可能です。(数値型のみ有効)
print(f"'{-123:p=10}'") # 文字埋め(int)
'-pppppp123'
なお、ゼロ埋めに関しては後述する 0
オプションが用意されていますから、以下2つは等価となります。
print(f"'{123:0=+10}'") # ゼロ埋め(fillオプション)
print(f"'{123:+010}'") # ゼロ埋め(0オプション)
# '+000000123'
# '+000000123'
表示型(type)
次に示す文字を指定することで数値を特別な表示に変換して出力します。
整数の表示型
intに限り次が利用できます。floatでは利用できません。
文字 | 説明 |
---|---|
b | 2進数 |
o | 8進数 |
d | 10進数 |
x | 16進数(英字は小文字) |
X | 16進数(英字は大文字) |
c | 数値に対応するUnicode文字 |
n |
d にロケール依存のセパレータを挿入する |
(None) |
d に同じ |
※ n
設定時の挙動は確認できませんでした。
g = 1500
print(f"g = {g:b}") # g = 10111011100
print(f"g = {g:o}") # g = 2734
print(f"g = {g:d}") # g = 1500
print(f"g = {g:x}") # g = 5dc
print(f"g = {g:X}") # g = 5DC
print(f"g = {g:c}") # g = ל
print(f"g = {g:n}") # g = 1500
print(f"g = {g:,d}") # g = 1,500
print(f"g = {g:}") # g = 1500
整数と小数の表現型
intとfloatの両方で利用できます。
文字 | 説明 |
---|---|
e | eを用いた指数表示します。 |
E |
e の代わりに E を使用する点を除いて e と同じです。 |
f | 固定小数点表記を行います。小数点以下桁数絶対主義といったところです。 |
F |
nan の代わりに NAN 、 inf の代わりに INF を使用する点を除いて f と同じです。 |
g | 与えられた小数の小数点以下桁数に応じて e と f を使い分けます。 |
G |
E と F に示した通り、特殊な文字が大文字であらわされます。 |
n | 略 |
% | 固定小数点表記(f )を利用した数値を100倍して末尾に % を付すことでパーセント表示します。 |
(None) | 主に g をとります。 |
h = 0.9345
print(f"h = {h:e}") # h = 9.345000e-01
print(f"h = {h:E}") # h = 9.345000E-01
print(f"h = {h:f}") # h = 0.934500
print(f"h = {h:F}") # h = 0.934500
# g, G については後節参照
print(f"h = {h:n}") # h = 0.9345
print(f"h = {h:%}") # h = 93.450000%
print(f"h = {h:}") # h = 0.9345
g
および G
の内部的な条件
g
は与えられた数値を自動で判定して e
(指数表記) か f
(固定小数点表記)を判定します。
具体的な分岐の基準は有効数字6桁であり、そのときに整数部の桁数が1を超えている際は e
の指数表記が適用され、そうでなければ f
の固定小数点表記が適用されます。
試したコードとその結果
ドキュメントに説明が用意されていますがすこし難しいので実践を通して条件を確認してみました。
小数部の桁数を増やす
print(f"{1.2345:g}") # 有効数字5桁
print(f"{1.23456:g}") # 有効数字6桁
print(f"{1.234567:g}") # 有効数字7桁
print(f"{0.1234567:g}") # 有効数字7桁
# 1.2345
# 1.23456
# 1.23457
# 0.123457
整数部の桁数を増やす
print(f"{12345:g}") # 有効数字5桁
print(f"{123456:g}") # 有効数字6桁
print(f"{1234567:g}") # 有効数字7桁
print(f"{1234567.89:g}") # 有効数字7桁
# 12345
# 123456
# 1.23457e+06
# 1.23457e+06
書式指定子の順番
書式指定子の順番について、公式ドキュメントでは次のように説明されています。
[[fill]align][sign][#][0][width][grouping_option][.precision][type]
見慣れない #
と 0
が登場してきましたので説明します。
-
#
は 表示型(type) での、2進数や8進数、16進数といった値に 接頭語 (prefix) として 0b, 0o, 0xを付けたり、有効数字表記g
において小数点以下を0埋めしたりする特殊オプションです。 -
0
は0専用の文字埋めオプションです。本来、文字埋めを行う際は fill にあたる先頭に文字を指定しますが、0のみは特別に 幅指定(width) の直前に設定することができます。
i = 1.56789
print(f"i = {i:010}") # 0埋めかつ、widthに10を指定した状態
print(f"i = {i:010.2f}") # 0埋めかつ、widthに10、.precisionに2、typeにfを指定した状態
# i = 0001.56789
# i = 0000001.57
なお、Python3.10 からはwidthに何も設定せずに 0
オプションを設定する、以下のような記述が可能になりました。
print(f"i = {i:0.2f}") # Python3.10から有効
以上2点を踏まえて、もりもりセットを組んでみたサンプルがこちらです。
print(f"{123.45678:>+010.4%}")
print(f"{123.45678:<010.1e}")
print(f"{123:^ #10b}")
print(f"{9999:a>#10X}")
# +12345.6780%
# 1.2e+02000
# 0b1111011
# aaaa0X270F
後記
つたない文章ではございましたが、お読みいただきありがとうございました!
皆さんのより良いPythonライフの一助になりましたら幸いです!