note.nkmk.me

Python, formatで書式変換(0埋め、指数表記、16進数など)

Date: 2017-08-18 / Modified: 2018-06-11 / tags: Python, 文字列操作

Pythonで数値や文字列を様々な書式に変換(フォーマット)する場合、組み込み関数format()または文字列メソッドstr.format()を使う。

ここでは、

  • 組み込み関数format()
  • 文字列メソッドstr.format()

の使い方を説明したあとで、

  • 左寄せ、中央寄せ、右寄せ
  • ゼロ埋め
  • 符号(プラス、マイナス)
  • 桁区切り(カンマ、アンダースコア)
  • 2進数、8進数、16進数
  • 小数点以下の桁数指定
  • 有効数字(有効桁数)
  • 指数表記
  • パーセント表示

といった書式に変換するための書式指定文字列について、サンプルコードとともに説明する。

日時datetime型のフォーマットについては以下の記事を参照。

なお、Python3.6から文字列メソッドstr.format()をより簡潔に記述できるf文字列(f-strings)が追加された。以下の記事を参照。

スポンサーリンク

組み込み関数format()

Python標準の組み込み関数としてformat()が用意されている。

概略は以下の通り。

  • format(value, format_spec)
    • 第一引数value: 元の値 / 文字列strや数値int, floatなど
    • 第二引数format_spec: 書式指定文字列 / 文字列str
    • 返り値: 書式化された文字列str

例を示す。書式指定文字列の種類や書き方については後述。

なお、ここでは第一引数に数値リテラルや文字列リテラルをそのまま使っているが、もちろんそれらの値が格納された変数でも構わない。

s = format(255, '04x')
print(s)
print(type(s))
# 00ff
# <class 'str'>

print(format('center', '*^16'))
# *****center*****
source: format.py

文字列メソッドstr.format()

文字列str型のメソッドにもformat()がある。

format()メソッドを呼び出す文字列str内の{}は置換フィールドと呼ばれ、format()メソッドの引数に置き換えられる。

書式指定文字列は置換フィールド{}内に:に続けて記述する。

返り値は書式化された文字列str

上述の組み込み関数format()と等価な処理は以下のようになる。

s = '{:04x}'.format(255)
print(s)
print(type(s))
# 00ff
# <class 'str'>

print('{:*^16}'.format('center'))
# *****center*****
source: format.py

ここでも引数に数値リテラルや文字列リテラルをそのまま使っているが、もちろん変数でもOK。

置換フィールドに対する引数の指定

順番通りに引数を指定(デフォルト)

置換フィールド{}は複数存在してもよく、デフォルトではメソッドの引数が順番に処理される。{}内の書式指定文字列を省略するとstr()で文字列に変換するだけになる。

文字列中に変数の値を挿入してprintで表示する場合などに便利。

print('{}-{}-{}'.format('100', '二百', 300))
# 100-二百-300
source: format.py

整数値に対して位置引数を指定

{0}{1}のように{}内に整数値を指定すると引数の順番に応じて出力される。同じ番号を繰り返し使うこともできる。文字列中に同じ値を挿入したい場合は便利。

print('{0}-{1}-{0}'.format('foo', 'bar'))
# foo-bar-foo
source: format.py

任意の名前(文字列)に対してキーワード引数を指定

{}内に任意の名前を指定し、キーワード引数として入力することも可能。

print('{year}年{month}月{day}日'.format(year=2018, month=1, day=11))
# 2018年1月11日
source: format.py

リスト、辞書を引数に指定

リストや辞書を引数に指定できる。

置換フィールド内でリストのインデックスや辞書のキーを[]で指定する。辞書のキーの指定では引用符'"は使わないので注意。

同じ引数を繰り返し使う場合は上述のように整数値や文字列(名前)を指定する必要がある。

l = ['one', 'two', 'three']
print('{0[0]}-{0[1]}-{0[2]}'.format(l))
# one-two-three

d1 = {'name': 'Alice', 'age': 20}
d2 = {'name': 'Bob', 'age': 30}
print('{0[name]} is {0[age]} years old.\n{1[name]} is {1[age]} years old.'.format(d1, d2))
# Alice is 20 years old.
# Bob is 30 years old.
source: format.py

リストに*をつけて引数に指定することで位置引数として展開したり、辞書に**をつけて引数に指定することでキーワード引数として展開することも可能。

l = ['one', 'two', 'three']
print('{}-{}-{}'.format(*l))
# one-two-three

d = {'name': 'Alice', 'age': 20}
print('{name} is {age} years old.'.format(**d))
# Alice is 20 years old.
source: format.py

波括弧{}の記述

format()メソッド内で波括弧{, }を書きたい場合は{{, }}のように2回繰り返して書く。バックスラッシュ\ ではエスケープできないので注意。

print('{{}}-{num}-{{{num}}}'.format(num=100))
# {}-100-{100}
source: format.py

書式指定文字列

いずれの場合も、書式を指定するには{}内の整数値や名前の文字列のあと:書式指定文字列のように書く。

print('{num:x}'.format(num=255))
# ff

print('{year}年{month:02}月{day:02}日'.format(year=2018, month=1, day=11))
# 2018年01月11日
source: format.py

以下、書式指定文字列による書式の指定方法について説明する。サンプルコードでは文字列メソッドstr.format()を使うが、組み込み関数format()でも同様の書式指定文字列が使用できる。組み込み関数format()では第二引数に書式指定文字列を指定する。

左寄せ、中央寄せ、右寄せ

<^>で左寄せ、中央寄せ、右寄せなどのアラインメントができる。全体の文字数を数値で指定する。

print('left  : {:<10}'.format(100))
print('center: {:^10}'.format(100))
print('right : {:>10}'.format(100))
# left  : 100       
# center:    100    
# right :        100
source: format.py

埋める文字を指定することもできる。上の例のように省略するとスペース。

一文字であれば全角でもOK。

print('left  : {:*<10}'.format(100))
print('center: {:a^10}'.format(100))
print('right : {:鬼>10}'.format(100))
# left  : 100*******
# center: aaa100aaaa
# right : 鬼鬼鬼鬼鬼鬼鬼100
source: format.py

>による右寄せは符号(-, +)が考慮されない。=を使うと符号のあとに続いて指定した文字で埋められる。+を明示したい場合は=のあとに+を書く。符号処理の詳細は後述。

print('sign: {:0>10}'.format(-100))
print('sign: {:0=10}'.format(-100))
print('sign: {:0=+10}'.format(100))
# sign: 000000-100
# sign: -000000100
# sign: +000000100
source: format.py

<^>は文字列に対しても指定できるが、=はエラーValueErrorになる。文字列に対して=で処理したい場合はint()などで数値に変換する必要がある。

# print('sign: {:0=10}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier

print('sign: {:0=10}'.format(int('-100')))
# sign: -000000100
source: format.py

浮動小数点数floatでも同様。小数点も一文字にカウントされる。

print('left  : {:*<10}'.format(1.23))
print('center: {:a^10}'.format(1.23))
print('right : {:鬼>10}'.format(1.23))
# left  : 1.23******
# center: aaa1.23aaa
# right : 鬼鬼鬼鬼鬼鬼1.23

print('sign: {:0>10}'.format(-1.23))
print('sign: {:0=10}'.format(-1.23))
print('sign: {:0=+10}'.format(1.23))
# sign: 00000-1.23
# sign: -000001.23
# sign: +000001.23
source: format.py

左寄せ、中央寄せ、右寄せについてはljust(), center(), rjust()という専用の文字列メソッドもある。以下の記事を参照。

0埋め

ゼロ埋めして桁数を合わせたい場合は埋める文字を0として右寄せする。

ゼロ埋めの場合はアラインメント記号を省略すると=を指定したものとして処理される。

print('zero padding: {:0=10}'.format(100))
print('zero padding: {:010}'.format(100))
# zero padding: 0000000100
# zero padding: 0000000100

print('zero padding: {:0=10}'.format(-100))
print('zero padding: {:010}'.format(-100))
# zero padding: -000000100
# zero padding: -000000100
source: format.py

=として処理されるので、上述のように引数に文字列を指定するとエラーになってしまう。注意。

# print('zero padding: {:010}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier
source: format.py

ゼロ埋めについてはzfill()という専用の文字列メソッドもある。以下の記事を参照。

符号(プラス、マイナス)

デフォルトでは負の数にのみ符号(マイナス-)が表示される。

書式化指定文字列に+をつけると正の数にも符号(プラス+)が表示される。スペースをつけると正の数の先頭に一文字分のスペースが表示され、負の数と桁数が揃う。

print('sign: {}'.format(100))
print('sign: {}'.format(-100))
# sign: 100
# sign: -100

print('sign: {:+}'.format(100))
print('sign: {:+}'.format(-100))
# sign: +100
# sign: -100

print('sign: {: }'.format(100))
print('sign: {: }'.format(-100))
# sign:  100
# sign: -100
source: format.py

上述のゼロ埋めなど任意の文字で埋める場合は注意が必要。+もスペースもつけないデフォルトでは正の数が一文字多く埋められてしまう。

print('sign: {:06}'.format(100))
print('sign: {:06}'.format(-100))
# sign: 000100
# sign: -00100

print('sign: {:+06}'.format(100))
print('sign: {:+06}'.format(-100))
# sign: +00100
# sign: -00100

print('sign: {: 06}'.format(100))
print('sign: {: 06}'.format(-100))
# sign:  00100
# sign: -00100
source: format.py

アラインメント記号を使う場合は、アラインメント記号のあとに符号の指定記号を書く。

print('sign: {:_>6}'.format(100))
print('sign: {:_>6}'.format(-100))
# sign: ___100
# sign: __-100

print('sign: {:_>+6}'.format(100))
print('sign: {:_>+6}'.format(-100))
# sign: __+100
# sign: __-100

print('sign: {:_> 6}'.format(100))
print('sign: {:_> 6}'.format(-100))
# sign: __ 100
# sign: __-100
source: format.py

桁区切り(カンマ、アンダースコア)

3ケタ毎にカンマ,またはアンダースコア_の区切りを入れる。大きい数値が見やすくなる。なお、アンダースコア_はPython3.6で追加されたオプションなので、それより前のバージョンでは使えない。

print('{:,}'.format(100000000))
# 100,000,000

print('{:_}'.format(100000000))
# 100_000_000
source: format.py

浮動小数点数float型の場合は整数部にのみ区切りが入る。

print('{:,}'.format(1234.56789))
# 1,234.56789
source: format.py

2進数、8進数、16進数

数値を2進数、8進数、16進数に変換して出力する。

  • b: 2進数
  • o: 8進数
  • d: 10進数
  • x, X: 16進数(大文字だとアルファベットが大文字表記)
print('bin: {:b}'.format(255))
print('oct: {:o}'.format(255))
print('dec: {:d}'.format(255))
print('hex: {:x}'.format(255))
print('HEX: {:X}'.format(255))
# bin: 11111111
# oct: 377
# dec: 255
# hex: ff
# HEX: FF
source: format.py

0埋めと組み合わせることもできる。2進数や16進数表記のときは桁を合わせるためによく使う。

print('bin: {:08b}'.format(255))
print('oct: {:08o}'.format(255))
print('dec: {:08d}'.format(255))
print('hex: {:08x}'.format(255))
print('HEX: {:08X}'.format(255))
# bin: 11111111
# oct: 00000377
# dec: 00000255
# hex: 000000ff
# HEX: 000000FF
source: format.py

書式化指定文字列の先頭に#をつけると、0b0xなどの接頭辞が加えられる。0埋めの文字数は接頭辞も考慮して指定する必要があるので注意。

print('bin: {:#010b}'.format(255))
print('oct: {:#010o}'.format(255))
print('dec: {:#010d}'.format(255))
print('hex: {:#010x}'.format(255))
print('HEX: {:#010X}'.format(255))
# bin: 0b11111111
# oct: 0o00000377
# dec: 0000000255
# hex: 0x000000ff
# HEX: 0X000000FF
source: format.py

2進数や16進数ではアンダースコア_の桁区切りのみ挿入できる(Python3.6以降)。4ケタ区切りとなる。0埋めの文字数はアンダースコアの数も考慮する必要がある。

print('hex: {:08x}'.format(255))
print('hex: {:09_x}'.format(255))
print('hex: {:#011_x}'.format(255))
# hex: 000000ff
# hex: 0000_00ff
# hex: 0x0000_00ff
source: format.py

2進数や16進数に書式を変換できるのは整数型intのみ。中身が数字であっても文字列strだとエラーValueErrorになる。int()で数値に変換すればOK。

# print('hex: {:08x}'.format('255'))
# ValueError: Unknown format code 'X' for object of type 'str'

print('hex: {:08x}'.format(int('255')))
# hex: 000000ff
source: format.py

Pythonにおける2進数、8進数、16進数の数値・文字列の変換についての詳細は以下の記事を参照。

小数点以下の桁数指定

小数点以下の桁数を指定するには、.[桁数]fとする。整数部の桁数によらず小数点以下が指定した桁数になる。

print('{:.2f}'.format(123.456))
print('{:.5f}'.format(123.456))
print('{:.3f}'.format(0.0001234))
# 123.46
# 123.45600
# 0.000
source: format.py

小数点の左側には上述の左寄せ、中央寄せ、右寄せ、ゼロ埋めの指定が可能。全体の桁数が指定した桁数になるように処理される。対象の値の桁数が指定した桁数よりも多い場合は何もされない。

print('{:>12.5f}'.format(123.456))
print('{:012.5f}'.format(123.456))
print('{:06.5f}'.format(123.456))
#    123.45600
# 000123.45600
# 123.45600
source: format.py

小数点以下に元の桁数よりも少ない桁数を指定すると値が丸められる。四捨五入ではなく偶数への丸めなので注意。0.50に丸められたりする。

print('{:.0f}'.format(0.4))
print('{:.0f}'.format(0.5))
print('{:.0f}'.format(0.6))
# 0
# 0
# 1
source: format.py

一般的な四捨五入にしたい場合は標準ライブラリdecimalのquantize()メソッドを使う方法がある。以下の記事を参照。

指数表記

浮動小数点float型の数値を文字列strに変換すると、桁数によって自動で指数表記になる。整数型intはならない。

print('{}'.format(0.0001234))
print('{}'.format(0.00001234))
# 0.0001234
# 1.234e-05

print('{}'.format(1234000000000000.0))
print('{}'.format(12340000000000000.0))
print('{}'.format(12340000000000000000000000))
# 1234000000000000.0
# 1.234e+16
# 12340000000000000000000000
source: format.py

書式化指定文字列にeまたはEを指定すると常に指数表記に変換することができる。出力に使われる文字がそれぞれe, Eとなる。

print('{:e}'.format(0.0001234))
print('{:E}'.format(0.0001234))
# 1.234000e-04
# 1.234000E-04
source: format.py

小数点以下の桁数を指定することも可能。整数部が常に1桁で小数点以下が指定した桁数になる。

print('{:.5e}'.format(0.0001234))
print('{:.2E}'.format(0.0001234))
# 1.23400e-04
# 1.23E-04

print('{:.5e}'.format(987.65))
print('{:.2E}'.format(987.65))
# 9.87650e+02
# 9.88E+02
source: format.py

左寄せ、中央寄せ、右寄せ、ゼロ埋めの指定をした場合、e-E+なども桁数(文字数)にカウントされるので注意。

print('{:>12.5e}'.format(987.65))
print('{:012.2E}'.format(987.65))
#  9.87650e+02
# 00009.88E+02
source: format.py

有効数字(有効桁数)

.[桁数]gとすると全体の桁数を指定できる。結果によって自動で指数表記になる。小数点以下の末尾の0は省略されてしまうので注意。

print('{:.2g}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.3g}'.format(0.0001234))
# 1.2e+02
# 123
# 123.456
# 0.000123
source: format.py

gを省略してもほとんどの場合で同様だが、整数で出力されるような場合のみ出力が異なる。gを省略すると整数にならない。

print('{:.2}'.format(123.456))
print('{:.3}'.format(123.456))
print('{:.8}'.format(123.456))
print('{:.3}'.format(0.0001234))
# 1.2e+02
# 1.23e+02
# 123.456
# 0.000123
source: format.py

同じ値を処理するとそれぞれ以下のようになる。

print('{:.3f}'.format(123.456))
print('{:.3e}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.3}'.format(123.456))
# 123.456
# 1.235e+02
# 123
# 1.23e+02

print('{:.8f}'.format(123.456))
print('{:.8e}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.8}'.format(123.456))
# 123.45600000
# 1.23456000e+02
# 123.456
# 123.456
source: format.py

gの場合や省略した場合は小数点以下の末尾の0は省略されてしまうので、有効数字(有効桁数)を合わせて出力したい場合はeまたはEの指数表記を使う。整数部が常に1桁で小数点以下が指定した桁数になるので、有効数字n桁の場合はn-1を指定すればよい。

print('{:.4e}'.format(123.456))
print('{:.4e}'.format(0.000012345))
print('{:.4e}'.format(12))
# 1.2346e+02
# 1.2345e-05
# 1.2000e+01
source: format.py

パーセント表示

書式化指定文字列に%を指定すると、数値floatまたはintの値を100倍して%を付けた文字列に変換する。

小数点以下の桁数を指定することも可能。デフォルトでは小数点以下が6桁。左寄せ、中央寄せ、右寄せ、ゼロ埋めもできる。%も文字数にカウントされる。

print('{:%}'.format(0.12345))
print('{:.2%}'.format(0.12345))
# 12.345000%
# 12.35%

print('{:%}'.format(10))
print('{:.2%}'.format(10))
# 1000.000000%
# 1000.00%

print('{:>7.2%}'.format(0.12345))
print('{:07.2%}'.format(0.12345))
#  12.35%
# 012.35%
source: format.py
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事