keisukeのブログ

***乱雑です!自分用のメモです!*** 統計や機械学習の勉強と、読み物を書く練習と、備忘録用のブログ

Python format string

Pythonのstringには.format()というフォーマット指定子のメソッドが用意されています.
C言語のsprintfをするときのように,文字列に他の文字を埋め込みたいときに使うやつです.
例えば,次のように使います:

>>> a = 'hoge'
>>> b = 123
>>> c = 3.14
>>> # format指定子
>>> print('a is {0}, b is {1}, and c is {2}.'.format(a,b,c))
>>> # %指定子
>>> print('a is %s, b is %d, and c is %f.' % (a,b,c))

個人的には%指定子のほうをよく使っていたのですが,.formatのほうが柔軟かつ推奨されているということでできるだけ.formatを使うことにしました.
.formatと%の違いで一番大きいことは,.formatでは(おそらく)オブジェクトの__str__メソッドを呼び出して文字列型に変換しているので,ユーザが型を意識せずに単に{0}などと書けば良いのに対し,%では%d,%f,%sなどのようにユーザが型を意識してフォーマットを出力する必要があることだと思います.
.formatのほうがよりダックタイピングらしさがありpythonicで良いっぽい雰囲気です.

.formatで便利そうなTipsをまとめると,

各指定子{0}の数字は省略可能.
>>> print('a is {}, b is {}, and c is {}.'.format('hoge', 123, 3.14))  # この場合,順番が考慮される
各指定子は変数名でアクセス可能(.formatは辞書形式).
>>> print('a is {a}, b is {b}, and c is {c}.'.format(c=3.14, b=123, a='hoge'))  # この場合,辞書形式なので順番は関係ない

よって,locals()をformatにそのまま投げることで今使っている変数名でそのまま文字列に埋め込み可能.

>>> a = 'hoge'
>>> b = 123
>>> c = 3.14
>>> print('a is {a}, b is {b}, and c is {c}.'.format(**locals()))

便利です*1

*1:locals()に**している理由: format()は辞書そのものを引数にはとらない(locals()は辞書を返す)ので,**で辞書を展開する必要があるため.つまり,.format({'a':'hoge', 'b':123})はダメなので,**によって.format(a:'hoge', b:123)へと展開している