Pythonのprint()で文字列を出力する時に、値を入れて出力することがあります。
例えばこんな形ですね。
name = '山田'
points = 85
print('期末テストで、' + name + 'さんは' + str(points) + '点でした。' )
変数のnameに名前を、pointsに85を入れて、これらの変数を+で繋げた文章をprint()で出力しています。数字はstr()で文字列にキャストしています。
実際に出力してみましょう。(ファイル名print_format.pyをAtomで実行してみます)
このように値を+で繋げて出力することは簡単にできますが、その変数を違うものに変更しなければならない場合は、その部分を書き換える必要があって、該当する部分をあちこち変更しなければならないことになって不便なこともあります。
この部分を置き換えなくてもいいような書き方ができるとコード管理が楽にもなります。
print()での出力の方法は、これまでの扱って来た中でも細かい説明なしに色々出て来ました。
ここでは、その様々なprintのフォーマットについて、整理しておきたいと思います。
%sを使った書式設定
「%s」を使えば、出力する文章の中に任意の文字列をプレースホルダーとして入れ込むことができます。
%sの基本的な使い方
基本的な使い方は、出力する文章の差し込みたい位置に%sをを置いて、その文章に続けて%に続けて表示したい文字列を置きます。
具体的にはコードを書いてみると、次のようになります。
print("好きな果物は、%sです。" %'リンゴ')
print("好きな果物は、%sと%sです。" %('リンゴ','ミカン'))
x = 'サッカー'
y = 'スノーボード'
print("好きなスポーツは、%sと%sです。"%(x,y))
複数入れ込みたい時は、%sを複数挿入し、指定する文字列は%の後にタプルで渡します。これを最後のように、変数にあらかじめ入れておいて、変数を渡しても構いません。
%sと%r
%sはstr()を示していて、渡した値を読みやすくした文字列を表示しますが、それ以外のものを使うことで別のものに変換して表現することができます。
%rはrepr()でリテラル文字として、渡した値をそのまま表示することができます。数値は%sで整数も少数も表示しますが、%dとすると整数を表示します。
具体的には次のコードになります。
print('I am studying %s.' %'Python')
print('I am studying %r.' %'Python')
print('I am studying %s.' %'\tPython')
print('I am studying %r.' %'\tPython')
print('I studied Python for %s hours.' %4.5)
print('I studied Python for %d hours.' %4.5)
%rを使って\tでタブを使っているものと、%dを使っているのがわかります。
実行するとこうなります。
%rを使うとクォーテーションも表示されているのがわかります。ですから、\tを使ってもタブとして表示されずにそのまま表示されています。%dのところは整数に変換されて表示されているのがわかります。
浮動小数点数
次は浮動小数点数の表示を使います。これには%のあとにfと(.)を使って表示する桁数を調整します。
具体的なコードで見て行きましょう。
print('浮動小数点数の表示: %1.2f' %(3.141592))
print('浮動小数点数の表示: %1.0f' %(3.141592))
print('浮動小数点数の表示: %1.5f' %(3.141592))
print('浮動小数点数の表示: %10.2f' %(3.141592))
print('浮動小数点数の表示: %20.2f' %(3.141592))
fの前のドットと数字に注目して見てみましょう。
ドットの左側は数値全体で含める最低文字列の数です。これを10、20とすると空白も含めて10文字、20文字になす。ドットの後の数字とfを使って小数点以下の桁数を指定します。
実行するとこうなります。
小数点以下の桁数、全体の長さの違いを確認してください。
%sなどを使っての文字列書式化のフォーマットは他にも色々あります。次の公式ドキュメントも参考にしてください。(これは古い書き方になります)
これらを次のように複数組み合わせて使っても問題ありません。
print('文字列: %s, 浮動小数点: %5.2f, リテラル: %r' %('Python!',3.1415,'Python!'))
.format()による書式設定
print文での書式で%sなどを使った方法を見てきましたが、これはどちらかというと古い書き方でPython2系から引き継いでいるものです。
ここでは.format()メソッドを使った方法を見ていこうと思います。こちらの方がよく使われているのではないでしょうか。
.format()の基本的な使い方
.format()を使うには、出力する文章に%sなどを置く代わりに波括弧{}を置きます。文章に続けて.format()と記述し、中に差し込む文字列を渡します。
具体的に見て行きましょう。
print('私が勉強しているプログラミング言語は、{}です。'.format('Python'))
クォーテーションで囲んだ文章の後にドットで続けてformat()を記述しています。文章の中にプレースフォルダとして{}が入っています。ここに文字列が挿入されます。
format()で指定した内容が、{}の中に入っているのがわかります。
プレースフォルダ{}の使い方
挿入部分の{}は色々な使い方ができて、操作の幅が広がります。(実行結果は最後にまとめて表示します)
インデックスで位置を指定
{}にインデックスを指定して、挿入する文字列を指定の位置に入れることができます。
print('新しい{1}を{2}のは、{0}ではない!'.format('老人','時代','創る'))
{}の中に数字を記載しています。format()に渡す文字列は0から順にインデックスが割り当てられています。
キーワードで位置を割り当てる
{}の中にキーワードを指定して、format()に対応させた文字列を渡します。
print(' 1st: {a}, 2nd: {b}, 3rd: {c}'.format(a=1,b='Two',c='三'))
キーワードに指定した位置に、formatの文字列が割り当て割れています。
キーワードを指定して重複を避ける
指定したキーワードは重複して再利用することができます。
print('{p}は{p}であり、{q}は{q}である。'.format(p='私',q='君'))
# print('%sは%sであり、%sは%sである。' %('私','私','君','君'))
コメントアウトした部分も同じ表現ですが、挿入する文字列をなんども渡さないといけません。その点、キーワードに指定したものは再度使うことができます。
これらの3つの方法をまとめて実行すると、次のようになります。
アライメントやパディングの位置の調整
.format()を使うと波括弧{}の中では、フィールドの長さ、左揃えや右揃えなどを割り当てることができます。
まずはこちらから見ていきましょう。
これはフィールドの長さを指定しています。
print('{0:8} | {1:9}'.format('Sports', 'Players'))
print('{0:8} | {1:9}'.format('Baseball', 9.))
print('{0:8} | {1:9}'.format('Soccer', 11))
コロンの左側は挿入する文字列のインデックスで、右側がフィールドの長さになっています。
文字列は左揃えで、数字は右揃えになっているのがデフォルトです。
ここで次のようにオプションとして<、^、>を使うと、それぞれ左揃え、中央揃え、右揃えを設定できます。
print('{0:<10} | {1:^10} | {2:>10}'.format('Left','Center','Right'))
print('{0:<10} | {1:^10} | {2:>10}'.format(100,200,300))
フィールドの長さを10としてそれぞれの位置を指定しています。
この位置指定のオプションの前に次のように文字を入れて空白部分を埋めて装飾することができます。
print('{0:*<10} | {1:=^10} | {2:*>10}'.format('Left','Center','Right'))
print('{0:*<10} | {1:=^10} | {2:*>10}'.format(100,200,300))
ここでは*印、=印を入れてみました。
フィールド幅と浮動小数点の表示はプレースホルダーの時と同様です。
# print('フィールド幅10、小数点以下2桁で表示:%10.2f' %3.141592)
print('フィールド幅10、小数点以下2桁で表示:{0:10.2f}'.format(3.141592))
フィールド幅10で、小数点以下2桁を表示指定ます。コメントアウトした方法と表示は同じです。
コロンのあとの空白が6文字、3,14で4文字の計10文字でフィールド幅10が埋められています。
.format()の書式設定に関する公式ドキュメントはこちらです。
f-strings
Python3.6からf-strings(フォーマット済み文字列リテラル)という書式が導入されました。これは、上記の.format()メソッドよりもスッキリした書き方になっています。
次のように、出力する文章の前にfをつけて、{}にそのまま変数を入れて使います。
lang = 'Python'
# print('私が勉強しているプログラミング言語は、{}です。'.format(lang))
print(f'私が勉強しているプログラミング言語は、{lang}です。')
これはコメントアウトした.format()を使った出力と同じです。
{}に変数を渡す時に、後ろに!rを加えるとrepr()と同じようにリテラル表記をします。
lang = 'Python'
print(f'私が勉強しているプログラミング言語は、{lang!r}です。')
ここでは、変数部分の文字列にクォーテーションがついたまま表示されているのがわかります。
フィールド幅と小数点以下の桁数表示は少し.format()と違うところがあります。
num = 12.3456789
# print("フィールド幅10、小数点以下4桁表示:{0:10.4f}".format(num))
print(f"フィールド幅10、小数点以下4桁表示:{num:{10}.{6}}")
コメントアウトしたformat()形式の書き方と比較するとわかりますが、波括弧{}に挿入する文字列の変数を渡し、コロンの後に波括弧{}でフィールド幅、コロンに続けて数字の桁数を与えています。小数点以下の桁数ではなく、数字全体の桁数になっていることに違いがあります。
小数点以下の表示で、指定の桁数よりも少ない数値の場合は次のように違いが出てきます。
num = 12.34
print("フィールド幅10、小数点以下4桁表示:{0:10.4f}".format(num))
print(f"フィールド幅10、小数点以下4桁表示:{num:{10}.{6}}")
print(f"フィールド幅10、小数点以下表示:{num:10.4f}")
数字を先ほどよりも短くしています。
今回は比較のためにformat()メソッドでも表示してみました。
少数点以下の数字が2桁なので4桁で表示しようとしても、f-stringsのこれまでの書き方では0で右側が埋められることになっていません。そこで、f-stringsでもformat()で書く時と同じように10.4fのようにフィールド幅と小数点以下の桁数を指定すると0で埋めることができます。
フォーマット済み文字列リテラル(f-strings)についての公式ドキュメントはこちらになります。
最後に
Pythonで文字列を出力するときにprint()で利用する色々なフォーマットを見てきました。
%sなどを使ったものはPython2系から引き継がれている書式です。それよりも新しい.format()メソッドは波括弧{}をプレースホルダーにして使います。ネットでのコード例では、.format()メソッドを使っている人が多いような気がします。
Python3.6からf-stringsの書式が導入され、format()メソッドよりも記述は楽になっています。
小数点以下の桁数の表示やフィールド幅、挿入する文字列のインデックスなどほぼどれも同じように使えますが、format()とf-stringsの小数点以下の桁数の足りない部分を0で埋める場合には工夫が必要です。
入門編で扱ってもよかったかも知れませんが、話が煩雑になるので応用編でまとめてみました。