Pythonで何らかの値を一定の書式に従って文字列に変換するにはformat関数や文字列のformatメソッド、f文字列を使用する。このときに一定の書式を指定するのに使うのが書式指定子である。その指定方法をまとめて紹介する。
# format関数の使用例
# format関数は第0引数の値を第1引数の書式指定子に従って書式化する
a = 100
format_spec = 'b' # 2進数表記に書式化
s = format(a, format_spec)
print(s) # 1100100
format_spec = '0=+5d' # 符号付き5桁の10進数表記に書式化
s = format(a, format_spec)
print(s) # +0100
# formatメソッドの使用例
a = 123
b = 456
c = 789
# 置換フィールドにformatメソッドの何番目の引数かを指定
s = '{0} + {1} + {2} = {3}'.format(a, b, c, a + b + c)
print(s) # 123 + 456 + 789 = 1368
# 置換フィールドに指定する引数の順番を省略
s = '{} + {} + {} = {}'.format(a, b, c, a + b + c)
print(s) # 123 + 456 + 789 = 1368
# formatメソッドの引数にキーワード引数を指定
s = '{a} + {b} + {c} = {total}'.format(a=a, b=b, c=c, total=a + b + c)
print(s) # 123 + 456 + 789 = 1368
# formatメソッドの引数に辞書を指定
d = {'a': 123, 'b': 456, 'c': 789}
s = '{a} + {b} + {c} = {total}'.format(**d, total=1368)
print(s) # 123 + 456 + 789 = 1368
# formatメソッドに書式指定子を記述
# 全体の文字数を10文字にして、小数点以下3桁の固定小数点表記に変換
a = 1234.5678
s = '{0:010.3f}'.format(a)
print(s) # 001234.568
# 書式指定子を渡すことも可能
format_spec = '010.3f'
s = '{a:{fs}}'.format(a=a, fs=format_spec) # OK
print(s) # 001234.568
# f文字列の使用例
a = 123
b = 456
s = f'{a} + {b} = {a + b}' # f文字列では置換フィールドに式を記述可能
print(s) # 123 + 456 = 579
s = f'{a=}' # Python 3.8以降。変数名と値を表示
print(s) # a=123
s = f'{a + 1 # コメント}' # Python 3.12以降。#以降は}や引用符を含めて
}' # コメントとして扱われるので、新しい行で置換フィールドを終了する
print(s) # 124
d = {'a': 123, 'b': 456}
s = f'{d['a']=}' # Python 3.12以降では置換フィールドで同じ引用符を使用可能
print(s) # d['a']=123
# f文字列で書式指定子を記述
a = 1234.5678
s = f'{a:.5e}' # 小数点以下5桁の指数表記
print(s) # 1.23457e+03
# fillオプションとalignオプションの使用例(文字寄せ)
# fill='_'/align='>'/width='6'
a = 1234
s = f'{a:_>6}' # 右寄せで6文字の10進数表記に変換。空白の代わりに_で埋める
print(s) # __1234
# align='>'/sign='+'/width='8'
a = 1234
s = '{:>+8}'.format(a) # 右寄せで符号付き8桁の10進数表記に変換
print(s) # +1234
# fill='0'/align='='/sign='+'/width='8'
a = 1234
s = f'{a:0=+8}' # 0埋めで符号付き8桁の10進数表記に変換
print(s) # +0001234
# fill='0'/align='>'/sign='+'/width='8'
s = '{:0>+8}'.format(a) # 符号の後を0埋めで右寄せの8桁の10進数表記に変換
print(s) # 000+1234
# align='^'/width='7'
foo = 'foo'
s = f'{foo:^7}' # 中央寄せで7文字の文字列に変換
s = s + '#' # 変換後の文字列の後ろにマーカーを追加
print(s) # foo #
# 'z'オプションの使用例(Python 3.11以降)
a = -0.0
s = f'{a:.3f}' # -0.0を小数点以下3桁の固定小数点に変換
print(s) # -0.000
s = '{:z.3f}'.format(a) # -0.0を+0.0に強制的に変換
print(s) # 0.000
# '#'オプションの使用例:通常とは別の形式に変換する
# type='b'
a = 1234
s = '{:b}'.format(a) # 2進数表記に変換
print(s) # 10011010010
# '#'/type='b'
s = f'{a:#b}' # 2進数表記に変換し、先頭に0bを付ける
print(s) # 0b10011010010
# '#'/type='X'
s = f'{a:#X}' # 16進数表記に変換(アルファベットは大文字)。先頭に0Xを付加
print(s) # 0X4D2
# '0'オプションの使用例:fill='0'/align='='と同様
a = 1234
s = '{:0>8}'.format(a) # 0埋めで右寄せの8桁の10進数表記に変換
print(s) # 00001234
s = '{:08}'.format(a) # 0埋めで右寄せの8桁の10進数表記に変換
print(s) # 00001234
# widthオプションの使用例
# width='8'
a = 1234
s = '{:8}'.format(a) # 右寄せで8桁の10進数表記に変換
print(s) # 1234
# align='<'/width='8'
a = 1234
s = f'{a:<8}' # 左寄せで8桁の10進数表記に変換
s = s + '#' # 変換後の文字列の後ろにマーカーを追加
print(s) # 1234 #
# width='8'
t = 'foobarbaz'
s = f'{t:8}' # widthオプションは最低の文字幅
print(s) # foobarbaz
# grouping_optionオプションの使用例
# grouping_option='_'/type='x'
a = 305441741
s = '{:_x}'.format(a) # 16進数表記に変換し、4桁ごとに_で区切る
print(s) # 1234_abcd
# grouping_option=','
a = 1234567890
s = f'{a:,}' # 3桁ごとに,で区切る
print(s) # 1,234,567,890
# precisionオプションの使用例
# precision='3'/type='f'
a = 1234.5678
s = '{:.3f}'.format(a) # 小数点以下3桁の固定小数点表記に変換
print(s) # 1234.568
# precision='3'/type='e'
a = 1234.5678
s = f'{a:.3e}' # 小数点以下3桁の指数表記に変換
print(s) # 1.235e+03
# precision='3'/type='g'
a = 1234.5678
s = f'{a:.3g}' # 小数点以下3桁の有効数字表記に変換
print(s) # 1.23e+03
# typeオプションの使用例
# type='n'
a = 1234
s = '{:n}'.format(a) # 2進数表記に変換
print(s) # 1234
import locale
loc_n = locale.getlocale(locale.LC_NUMERIC) # 現在のロケールを保存
locale.setlocale(locale.LC_NUMERIC, 'ja_JP.UTF-8')
s = f'{a:n}' # ロケールに従った数値表記に変換
print(s) # 1,234
locale.setlocale(locale.LC_NUMERIC, loc_n) # 元に戻す
オプション | 説明 | 指定可能な値 |
---|---|---|
fill | 0埋めなどで使用する文字 | 任意の文字 |
align | widthで指定した文字数の中での文字寄せの方法 | '<':左寄せ '>':右寄せ '=':符号の後を文字埋め '^':中央寄せ |
sign | 符号の付け方の指定 | '+':常に符号を表示 '-':負数のみ符号を表示 ' ':正数については符号の代わりに空白文字を、負数については符号を表示 |
'z' | -0.0を変換する場合に、他のオプションで指定された形で書式化した上で+0.0に変換する | 'z'をそのまま記述 |
'#' | 数値を通常とは異なる形式に変換。 typeオプションに'b'を指定して整数を2進表記する場合は'0b'を前置 typeオプションに'o'を指定して整数を8進表記する場合は'0o'を前置 typeオプションに'x'または'X'を指定して整数を16進表記する場合は'0x'または'0X'を前置する 浮動小数点数と複素数については、小数点以下の値がなくとも常に小数点文字を表示。また、typeオプションに'g'または'G'を指定した場合、末尾の0を省略しないようになる |
'#'をそのまま記述 |
'0' | fillオプションに'0'を、alignオプションに'='を指定したのと同じ効果を持つ | 'z'をそのまま記述 |
width | 置換フィールドの最小幅の指定 | 10進の整数値 |
grouping_option | 数値が読みやすくなるようにカンマまたはアンダースコアを表示 | ',':3桁ごとにカンマを表示(浮動小数点数を書式化する際には小数点よりも前の部分だけが対象となる) '_':typeオプションに'd'を指定して整数を書式化するときには3桁ごとに、typeオプションに'b'、'o'、'x'、'X'を指定して書式化するときには4桁ごとにアンダースコアを表示(浮動小数点数を書式化する場合には小数点よりも前の部分が対象となる) |
'.'precision | ドット「.」に続けて指定する | 10進の整数 typeオプションに'e'、'E'、'f'、'F'を指定している場合は小数点以下の桁数を、'g'、'G'を指定した場合は整数部と小数部の合計桁数を指定することになる |
type | データの表現方法の指定 | 整数の表現型 'b':2進数 'c':文字(数値をUnicodeのコードポイントとしてUnicode文字に変換) 'd':10進数 'o':8進数 'x':16進数。アルファベットは小文字表記。'#'オプションが指定されると'0x'が前置される 'X':16進数。アルファベットは大文字表記。'#'オプションが指定されると'0X'が前置される 'n':数値。現在のロケールに合わせて区切り文字が挿入される(1000の位のカンマなど。それ以外は'd'と同様) float型の表現型 'e'、'E':指数表記。'e'は「1.230e+00」のような、'E'は「1.230E+00」のような表記になる 'f'、'F':固定小数点数表記。'f'と'F'の違いは非数(NaN)が'nan'と表記されるか'NAN'と表記されるか、また無限が'inf'と表現されるか'INF'と表現されるか 'g'、'G':汎用フォーマット(変換する値によって指数表記と固定小数点表記のどちらか書式化されるが決まる) 'n':数値。現在のロケールに合わせて区切り文字が表示されることを除けば'g'と同様 '%':パーセンテージ表記 文字列の表現型 's':文字列(デフォルト値) |
書式指定ミニ言語まとめ |
Pythonでは数値や文字列を何らかの形式に書式化するのにformat関数、文字列のformatメソッド、f文字列を使用する。そして、この「何らかの形式」を指定するのに使うのが「書式指定子」だ。その仕様はPythonのドキュメント「書式指定ミニ言語仕様」で述べられている。
書式指定子の詳細に入る前に、format関数、文字列のformatメソッド、f文字列の使い方も簡単にまとめておく。
*1 正確には「!s」などのconversionフィールドの指定も可能だが、本稿では説明を省略する(f文字列も同様)。
以下にformat関数の使用例を示す。
# format関数は第0引数の値を第1引数の書式指定子に従って書式化する
a = 100
format_spec = 'b' # 2進数表記に書式化
s = format(a, format_spec)
print(s) # 1100100
format_spec = '0=+5d' # 符号付き5桁の10進数表記に書式化
s = format(a, format_spec)
print(s) # +0100
format関数では第0引数に変換したい値を、第1引数に書式指定子を指定する。最初の例では書式指定子(format_spec)は'b'なので2進数表記に変換されている。次の例では、書式指定子は'0=+5d'となっているが、これは「常に符号を表示し、符号の後を0埋め、最低文字数は5文字で10進数値に変換」を意味しているので「+0100」という結果になる。
以下は文字列のformatメソッドの使用例だ。
a = 123
b = 456
c = 789
# 置換フィールドにformatメソッドの何番目の引数かを指定
s = '{0} + {1} + {2} = {3}'.format(a, b, c, a + b + c)
print(s) # 123 + 456 + 789 = 1368
# 置換フィールドに指定する引数の順番を省略
s = '{} + {} + {} = {}'.format(a, b, c, a + b + c)
print(s) # 123 + 456 + 789 = 1368
# formatメソッドの引数にキーワード引数を指定
s = '{a} + {b} + {c} = {total}'.format(a=a, b=b, c=c, total=a + b + c)
print(s) # 123 + 456 + 789 = 1368
# formatメソッドの引数に辞書を指定
d = {'a': 123, 'b': 456, 'c': 789}
s = '{a} + {b} + {c} = {total}'.format(**d, total=1368)
print(s) # 123 + 456 + 789 = 1368
formatメソッドでは引数の渡し方が幾つかある。位置引数で渡した場合、書式指定文字列内の置換フィールド('{}'で囲まれた部分)では引数の並び順を0始まりで指定して、どの変数の値をどの置換フィールドに埋め込むかを指定する(最初の例)。あるいは置換フィールドを'{}'としたときには、formatメソッドに渡した引数の値が前から順に使われる。キーワード引数や辞書を使うと、キーワード引数の名前や辞書のキーを置換フィールドでどの値を使用するかを指定できる。3つ目と4つ目の例がそうなっている。
置換フィールドに書式指定子を記述するには、コロン「:」に続けてそれを書く。以下に例を示す。
# 全体の文字数を10文字にして、小数点以下3桁の固定小数点表記に変換
a = 1234.5678
s = '{0:010.3f}'.format(a)
print(s) # 001234.568
この例では、コロンに続く「'010.3f」が書式指定子となる。これは「0埋め、最低文字幅は10文字、小数点以下3桁の固定小数点」に変換することを意味している。そのため、1234.5678はそれに従って「001234.568」となっている。
なお、以下のようにformatメソッドの引数として書式指定子を渡すことも可能だ。
format_spec = '010.3f'
s = '{a:{fs}}'.format(a=a, fs=format_spec) # OK
print(s) # 001234.568
この例ではfsキーワード引数に書式指定子を渡し、それを書式指定文字列内の置換フィールド内の書式指定部分で「:{fs}」のようにして書式指定子として使用している。
最後にf文字列の使用例を示す。
a = 123
b = 456
s = f'{a} + {b} = {a + b}' # f文字列では置換フィールドに式を記述可能
print(s) # 123 + 456 = 579
formatメソッドの置換フィールドでは、渡された引数のどれを埋め込むかを順番や名前を使って指定することしかできないが、f文字列の置換フィールドには単に変数名を指定するだけではなく、式も記述できるのが大きな違いといえる(上の例の'{a + b}'というところ)。
また、Python 3.8以降では「'{変数名=}'」と書くことで「変数名=値」という文字列が置換フィールドに埋め込まれる。以下に例を示す。
s = f'{a=}' # Python 3.8以降。変数名と値を表示
print(s) # a=123
さらにPython 3.12以降では置換フィールド内にコメントを書いたり、文字列を囲むクオート文字と同じ文字を置換フィールドに記述したりすることができる。
s = f'{a + 1 # コメント}' # Python 3.12以降。#以降は}や引用符を含めて
}' # コメントとして扱われるので、新しい行で置換フィールドを終了する
print(s) # 124
d = {'a': 123, 'b': 456}
s = f'{d['a']=}' # Python 3.12以降では置換フィールドで同じ引用符を使用可能
print(s) # d['a']=123
書式指定子の書き方自体はformatメソッドの置換フィールドと同様で、コロンの後にそれを記述する。以下に例を示す。
a = 1234.5678
s = f'{a:.5e}' # 小数点以下5桁の指数表記
print(s) # 1.23457e+03
以上、簡単だがformat関数とformatメソッド、f文字列の使い方をまとめた。以下では書式指定子についてまとめる。
書式指定子はおおよそ次の要素を含む(どの要素も省略可能だが、全てを省略することはできない)。
[fill[align]][sign]["z"]["#"]["0"][width][grouping_option]["."precision][type]
以下ではこれらのオプションの使い方を見ていく。
fillオプションは文字埋めをしたいときに、どの文字を使うかを指定する。alignオプションには以下のいずれかを指定する。
以下に例を示す。先頭のコメントにオプションの値を記述しているので、それを参考に出力結果と書式指定子の関係を確認してほしい。なお、以下ではformatメソッドとf文字列を混在して使っている。
# fill='_'/align='>'/width='6'
a = 1234
s = f'{a:_>6}' # 右寄せで6文字の10進数表記に変換。空白の代わりに_で埋める
print(s) # __1234
# align='>'/sign='+'/width='8'
a = 1234
s = '{:>+8}'.format(a) # 右寄せで符号付き8桁の10進数表記に変換
print(s) # +1234
# fill='0'/align='='/sign='+'/width='8'
a = 1234
s = f'{a:0=+8}' # 0埋めで符号付き8桁の10進数表記に変換
print(s) # +0001234
# fill='0'/align='>'/sign='+'/width='8'
s = '{:0>+8}'.format(a) # 符号の後を0埋めで右寄せの8桁の10進数表記に変換
print(s) # 000+1234
# align='^'/width='7'
foo = 'foo'
s = f'{foo:^7}' # 中央寄せで7文字の文字列に変換
s = s + '#' # 変換後の文字列の後ろにマーカーを追加
print(s) # foo #
最後の例では、中央寄せを指定しているので(align='^')、出力結果で空白文字が出力されていることを確認できるように文字列末尾に'#'を付加した。
'z'オプションは-0.0を、書式指定子に従って変換した後に、+0.0に強制的に変換することを指示する(Python 3.11以降)。
a = -0.0
s = f'{a:.3f}' # -0.0を小数点以下3桁の固定小数点に変換
print(s) # -0.000
s = '{:z.3f}'.format(a) # -0.0を+0.0に強制的に変換
print(s) # 0.000
'#'オプションは通常とは異なる形式に変換することを指示するものだ。主に以下がその効能といえる。
これ以外に浮動小数点数や複素数を変換する際に'#'を指定すると、小数点以下が0であっても常に小数点を含むようになるなどがあるが、ここでは例を省略する。
以下は'#'オプションを指定せずにtypeオプションに'b'(2進数表記に変換)を指定する場合と、'#'オプションを指定してtypeオプションに'b'を指定した場合の例だ。
# type='b'
a = 1234
s = '{:b}'.format(a) # 2進数表記に変換
print(s) # 10011010010
# '#'/type='b'
s = f'{a:#b}' # 2進数表記に変換し、先頭に0bを付ける
print(s) # 0b10011010010
'#'オプションを指定すると'0b'が付加されることを確認してほしい。
以下はtypeオプションに'X'(16進数表記に変換)を指定した場合の例だ。
# '#'/type='X'
s = f'{a:#X}' # 16進数表記に変換(アルファベットは大文字)。先頭に0Xを付加
print(s) # 0X4D2
この場合はアルファベットが全て大文字になる。
'0'オプションを指定すると、fillオプションに'0'を、alignオプションに'='を指定したのと同様な結果が得られる。以下に両者の例を示す。
a = 1234
s = '{:0>8}'.format(a) # 0埋めで右寄せの8桁の10進数表記に変換
print(s) # 00001234
s = '{:08}'.format(a) # 0埋めで右寄せの8桁の10進数表記に変換
print(s) # 00001234
widthオプションは変換後の値の最小文字幅を指定する。以下に例を示す。
# width='8'
a = 1234
s = '{:8}'.format(a) # 右寄せで8桁の10進数表記に変換
print(s) # 1234
# align='<'/width='8'
a = 1234
s = f'{a:<8}' # 左寄せで8桁の10進数表記に変換
s = s + '#' # 変換後の文字列の後ろにマーカーを追加
print(s) # 1234 #
# width='8'
t = 'foobarbaz'
s = f'{t:8}' # widthオプションは最低の文字幅
print(s) # foobarbaz
最後の例に示した通り、widthオプションで指定した値よりも、変換後の値の方が長い文字となることもあることには注意しよう。
grouping_optionオプションは、数値を区切るカンマやアンダースコアを表示するかどうかの指定に使う。指定できるのは以下の2つで、指定しなければ区切り文字は表示されない。
以下に例を示す。
# grouping_option='_'/type='x'
a = 305441741
s = '{:_x}'.format(a) # 16進数表記に変換し、4桁ごとに_で区切る
print(s) # 1234_abcd
# grouping_option=','
a = 1234567890
s = f'{a:,}' # 3桁ごとに,で区切る
print(s) # 1,234,567,890
なお、小数点以下の値については区切り文字は表示されない。
precisionオプションはドット「.」に続けて、10進の整数値を指定する。これはtypeオプションの値によって解釈が異なる(typeオプションに'd'などの整数の表現型を指定したときには、このオプションは指定できない)。
以下に例を示す。
# precision='3'/type='f'
a = 1234.5678
s = '{:.3f}'.format(a) # 小数点以下3桁の固定小数点表記に変換
print(s) # 1234.568
# precision='3'/type='e'
a = 1234.5678
s = f'{a:.3e}' # 小数点以下3桁の指数表記に変換
print(s) # 1.235e+03
# precision='3'/type='g'
a = 1234.5678
s = f'{a:.3g}' # 小数点以下3桁の有効数字表記に変換
print(s) # 1.23e+03
全てprecisionオプションの値は3を指定しているが、typeオプションに'g'を指定した場合は小数点以上と小数点以下の桁数が3になっている点に注意されたい。
typeオプションは、データの取り扱い方を指示する。多くの値を指定できる。以下に大ざっぱにまとめておく。
多くの値は既に例で使用しているので、ここでは'n'を指定した場合の例を示す。
# type='n'
a = 1234
s = '{:n}'.format(a) # 2進数表記に変換
print(s) # 1234
ロケールの設定を特にしていなければ、上のようにカンマなどが変換後の文字列に含まれることはない。そこで、ロケールのLC_NUMERICに'ja_JP.UTF-8'を設定して、上と同じコードを実行してみよう。
import locale
loc_n = locale.getlocale(locale.LC_NUMERIC) # 現在のロケールを保存
locale.setlocale(locale.LC_NUMERIC, 'ja_JP.UTF-8')
s = f'{a:n}' # ロケールに従った数値表記に変換
print(s) # 1,234
locale.setlocale(locale.LC_NUMERIC, loc_n) # 元に戻す
すると、このように1000の位にカンマが挿入された。'n'を指定する場合、ロケールを設定していないと、期待したものとは異なる結果になるかもしれないので注意しよう。
Copyright© Digital Advantage Corp. All Rights Reserved.