Pythonにおける文字列のフォーマット付け

Last modified: 2021-07-24

Pythonの文字列において

  • 文字列の整形についての指定を行う “フォーマット文字列”
  • その中に実際に入る値

を指定して整形済みの文字列を得るための新しい書き方がバージョン3系以上で使用できる。

古い書き方と新しい書き方2つ

  • 古い書き方: 古い書式のフォーマット文字列の入った文字列オブジェクトの後ろに % を付けて、その後ろにタプルなどでそれぞれの値を渡す
  • str.format()による新しい書き方: 新しい書式のフォーマット文字列の入った文字列オブジェクトのメンバ関数format()の引数にそれぞれの値を渡す
  • fの付いたフォーマット文字列(Formatted string literals)を用いる書き方(Python 3.6以上のみ): 波括弧の中に変数名やその書式についてを直接記述

バージョン3.5系までのPythonは既にサポートが終了しており、セキュリティ関係を含めて今後不具合は修正されることはないため、使用するべきではない。

本記事では比較のために古い書き方を紹介している部分もあるが、主に2番目のstr.format()を用いた方法についてを扱う。

例として

  • 123999の2つの値をスペース区切りで続けて記述
  • 123は5桁で表記し、存在しない桁は0にする
  • 999は小数第二位まで表記

としたい場合、古い書式では

>>> '%05d %.2f' % (123, 999)  # %記号を用いる古い書式
'00123 999.00'

としていたが、format()を用いると

>>> '{:05d} {:.2f}'.format(123, 999)  # 文字列型のメンバ関数format()による指定
'00123 999.00'

となる。

最後に、変数abにそれぞれの値が入っている状態で “Formatted string literals” を用いると

>>> a = 123; b = 999  # 事前に変数に入っている状態を作る
>>> f'{a:05d} {b:.2f}'
'00123 999.00'

となる。

str.format()の書き方

フォーマット部分の書式

format()を呼び出す文字列の中身に記述する個別の波括弧内の書式は

{[そこに入れたい引数の順番(0から)]([!r もしくは !s])(:[printf()系関数のフラグ文字列("%" の後ろの部分)])}

となる。

最もシンプルな形は{}で、これは形式の変換を行わずにそのままの内容が入る。フォーマット文字列中に複数の{}がある場合、format()の引数は複数個指定することになるが、その順番は{}が値と対応するように同じ順番にする必要がある。

引数が複数あるときに{0}{1}のように数字を付けると、この値の付け方しだいで波括弧で囲まれた部分の順番と引数の順番を違ったものにできる。

>>> '{1:05d} {0:.2f}'.format(123, 999)  # 123を2番目、999を1番目に入るようにする
'00999 123.00'

!r!sの指定をするとそれぞれrepr()str()による変換が入る。

>>> '{:s}'.format(str(12345))     # str()を用いたもの
'12345'

>>> '{!s:s}'.format(12345)        # "!s" 指定をしたもの
'12345'

>>> '{:s}'.format(repr('12345'))  # repr()を用いたもの
"'12345'"

>>> '{!r:s}'.format('12345')      # "!r" 指定をしたもの
"'12345'"

タプルをstr.format()の引数に用いる

波括弧の部分の個数と要素数の同じなタプル変数を引数にしたい場合はそのタプル変数名の左に*を付ける。

>>> t = (123, 999)
>>> '{:05d} {:.2f}'.format(*t)
'00123 999.00'

タプルの要素数よりも多くの引数が必要で、なおかつそのタプル以外の値を用いるには、色々な書き方がある。

>>> '{:05d} {:.2f} {}'.format(t[0], t[1], 50)  # 2要素タプルの個別の要素と別の数値を指定
'00123 999.00 50'

>>> '{:05d} {:.2f} {}'.format(*t, 50)  # 2要素タプルと別の数値を指定
'00123 999.00 50'

>>> '{1:05d} {2:.2f} {0}'.format(50, *t)  # 順を入れ替えて数値と2要素タプルを指定
'00123 999.00 50'

出力がある長さより短いときに文字列の後ろをスペースで埋める

例えば、labelという文字列をそのまま入れると

>>> '[{}]'.format('label')
'[label]'

となるが、{:10}とすると

>>> '[{:10}]'.format('label')
'[label     ]'

となり、波括弧で囲まれた部分に引数の値を入れて10文字に足らない部分がスペースで埋められる。

もちろん、それよりも入力が長い場合は

>>> '[{:10}]'.format('labelstring')
'[labelstring]'

そのまま出力される。

名前による対応と辞書を用いた指定

format()の引数にキーワード引数もしくは辞書を用いて名前と値を対応付ける形で指定することもできる。

%を用いる古い書式で

>>> '%(key)s=%(value)d' % {'key': 'keyname', 'value': 12345}  # 古い書式
'keyname=12345'

のように記述していたものは、format()でキーワード引数を用いると

>>> '{key}={value}'.format(key='keyname', value=12345)
'keyname=12345'

のように、辞書を用いると

>>> d = {'key': 'keyname', 'value': 12345}
>>> '{key}={value}'.format(**d)
'keyname=12345'

のようになる。辞書の場合は辞書変数名の前に**を付ける。

なお、既にバージョン3.6系以上のPythonしかサポートされていない状況になっているため、このようにして変数を渡すならf付きの文字列 “Formatted string literals” の書き方をしたほうがシンプルに書ける。

>>> key = 'keyname'; value = 12345  # 事前に変数に入っている状態を作る
>>> f'{key}={value}'
'keyname=12345'

コンマの桁区切りについて

バージョン3以上のPythonでは{:,}でコンマの桁区切りが

>>> '{:,}'.format(314159265358979)
'314,159,265,358,979'

このように簡単にできる。

左/中央/右寄せ

{[引数の順番]:([空白に表示する文字列])[<(左寄せ) もしくは ^(中央寄せ) もしくは >(右寄せ)][全体の長さ]}

のようにすると余った部分を用いて左/中央/右寄せができる。

>>> '{:_<10}'.format('test')
'test______'
>>> '{:_^10}'.format('test')
'___test___'
>>> '{:_>10}'.format('test')
'______test'

空白に表示する文字列は省略すると半角スペースになる。

関連:C#言語のフォーマット付け

Pythonのstr.format()で用いる波括弧内の記法はC#言語のフォーマット指定と似ているが、厳密には異なる。csharpコマンドのシェルで試すと

csharp> Console.WriteLine("{0:05d} {1:.2f}", 123, 999);
1235d 2f
csharp> Console.WriteLine("{1:05d} {0:.2f}", 123, 999);
9995d 2f

となり、意図しない出力になる。%05d%.2fのような形式になるようにするには

("d" や "f" の後ろに数字を付ける書き方)
csharp> Console.WriteLine("{0:d5} {1:f2}", 123, 999);
00123 999.00
(引数の順番を逆にしている)
csharp> Console.WriteLine("{1:d5} {0:f2}", 123, 999);
00999 123.00
(実際の値の見た目に合った書き方)
csharp> Console.WriteLine("{0:00000} {1:.00}", 123, 999);
00123 999.00

のようにする。この例ではSystem.Console.WriteLine()を用いて端末に表示しているが、System.String.Format()を用いてフォーマット付けされた文字列を得る形で使うこともできる。