Pythonのf文字列(フォーマット済み文字列リテラル)の使い方
Python3.6からf文字列(f-strings、フォーマット文字列、フォーマット済み文字列リテラル)という仕組みが導入され、冗長だった文字列メソッドformat()
をより簡単に書けるようになった。
文字列メソッドformat()
や組み込み関数format()
、書式指定文字列の詳細については以下の記事を参照。
f文字列(フォーマット文字列)の基本的な使い方
文字列メソッドformat()
では、順番に引数を指定したり名前を決めてキーワード引数で指定したりして置換フィールド{}
に値を挿入できる。
a = 123
b = 'abc'
print('{} and {}'.format(a, b))
# 123 and abc
print('{first} and {second}'.format(first=a, second=b))
# 123 and abc
f文字列(f-strings)は文字列リテラルの前にf
またはF
を置く(f'...'
, F'...'
)。文字列中の置換フィールドに変数をそのまま指定できる。
print(f'{a} and {b}')
# 123 and abc
print(F'{a} and {b}')
# 123 and abc
通常の文字列リテラルと同様、シングルクォート'
だけでなくダブルクォート"
でもトリプルクォート'''
, """
でもよい。
print(f"{a} and {b}")
# 123 and abc
print(f'''{a} and {b}''')
# 123 and abc
print(f"""{a} and {b}""")
# 123 and abc
書式指定
文字列メソッドformat()
と同様に、f文字列でも置換フィールド{}
でコロン:
のあとに書式指定文字列を指定することで様々な書式を指定できる。
いくつか例を示す。詳細は以下の記事を参照。
右寄せ、中央寄せ、左寄せ
s = 'abc'
print(f'right : {s:*>8}')
print(f'center: {s:*^8}')
print(f'left : {s:*<8}')
# right : *****abc
# center: **abc***
# left : abc*****
ゼロ埋め
i = 1234
print(f'zero padding: {i:08}')
# zero padding: 00001234
桁区切り
i = 1234567890
print(f'comma: {i:,}')
# comma: 1,234,567,890
2進数、8進数、16進数
i = 255
print(f'bin : {i:b}')
print(f'oct : {i:o}')
print(f'hex(lower): {i:x}')
print(f'hex(upper): {i:X}')
# bin : 11111111
# oct : 377
# hex(lower): ff
# hex(upper): FF
print(f'bin : {i:08b}')
print(f'oct : {i:08o}')
print(f'hex(lower): {i:08x}')
print(f'hex(upper): {i:08X}')
# bin : 11111111
# oct : 00000377
# hex(lower): 000000ff
# hex(upper): 000000FF
print(f'bin : {i:#010b}')
print(f'oct : {i:#010o}')
print(f'hex(lower): {i:#010x}')
print(f'hex(upper): {i:#010X}')
# bin : 0b11111111
# oct : 0o00000377
# hex(lower): 0x000000ff
# hex(upper): 0X000000FF
小数点以下の桁数、有効数字(有効桁数)
f = 12.3456
print(f'decimal places : {f:.3f}')
print(f'significant digits: {f:.3g}')
# decimal places : 12.346
# significant digits: 12.3
指数表記
f = 12.3456
print(f'exponent(lower): {f:.3e}')
print(f'exponent(upper): {f:.3E}')
# exponent(lower): 1.235e+01
# exponent(upper): 1.235E+01
パーセント表記
f = 0.123
print(f'percent: {f:.2%}')
# percent: 12.30%
日時(datetime)
import datetime
dt = datetime.datetime(2020, 1, 5, 20, 15, 30)
print(f'datetime: {dt}')
# datetime: 2020-01-05 20:15:30
print(f'datetime: {dt:%A, %m/%d/%Y %I:%M:%S %p}')
# datetime: Sunday, 01/05/2020 08:15:30 PM
print(f'datetime: {dt.isoformat()}')
# datetime: 2020-01-05T20:15:30
datetimeモジュールの詳細は以下の記事を参照。
最後の例のように、ISO 8601形式の文字列に変換する場合は書式化コードを指定するよりisoformat()
メソッドを使う方が楽。
波括弧{}の扱い
文字列メソッドformat()
と同様に、f文字列中に波括弧{}
を記述したい場合は{{
, }}
のように2回続けて書く。
n = 123
print(f'{{}}-{n}-{{{n}}}')
# {}-123-{123}
ネストした置換フィールド
文字列メソッドformat()
と同様に、f文字列でも置換フィールド内に置換フィールドを書くことができる。書式指定文字列の数値を変数で指定したりできる。
n = 123
i = 8
print('{n:0{i}}'.format(n=n, i=i))
# 00000123
print(f'{n:0{i}}')
# 00000123
こんなことも可能。
f = 1.2345
for i in range(5):
print(f'{f:.{i}f}')
# 1
# 1.2
# 1.23
# 1.234
# 1.2345
raw文字列との組み合わせ
通常の文字列中では特殊文字を表すためにバックスラッシュ\
を使う。文字列リテラルの先頭にr
またはR
をつけたraw文字列ではバックスラッシュによるエスケープが無視される。
print('x\ty')
# x y
print(r'x\ty')
# x\ty
文字列リテラルの先頭にr
とf
を両方つけることでraw文字列かつf文字列として処理される。r
とf
の順番はどちらでもよく、大文字でもよい。
x = 'XXX'
y = 'YYY'
print(f'{x}\t{y}')
# XXX YYY
print(rf'{x}\t{y}')
# XXX\tYYY
print(FR'{x}\t{y}')
# XXX\tYYY
なお、raw文字列でもそうでなくても置換フィールド内ではバックスラッシュは使えない。後述の辞書のキー指定の際には注意。
文字列メソッドformat()との違い
f文字列では式を使用可能
文字列メソッドformat()
では置換フィールド内に式を記述することはできず、エラーKeyError
になる。
a = 3
b = 4
# print('{a} + {b} = {a + b}'.format(a=a, b=b))
# KeyError: 'a + b'
f文字列では置換フィールド内に式を記述できる。評価された値に対して書式指定もできる。
print(f'{a} + {b} = {a + b}')
# 3 + 4 = 7
print(f'{a} * {b} = {a * b}')
# 3 * 4 = 12
print(f'{a} / {b} = {a / b:.2e}')
# 3 / 4 = 7.50e-01
辞書のキー指定方法
辞書dict
を置換フィールドに指定する場合、文字列メソッドformat()
ではキーの指定に引用符'
, "
は不要。引用符をつけるとエラーになる。
d = {'key1': 10, 'key2': 20}
print('{0[key1]}, {0[key2]}'.format(d))
# 10, 20
# print('{0["key1"]}, {0["key2"]}'.format(d))
# KeyError: '"key1"'
f文字列では置換フィールドがそのまま式として評価されるので引用符が必要。引用符が無いとエラーになる。
print(f'{d["key1"]}, {d["key2"]}')
# 10, 20
# print(f'{d[key1]}, {d[key2]}')
# NameError: name 'key1' is not defined
また通常の文字列と同様にf文字列全体を囲む引用符と同じ引用符は使えないので、全体を'
で囲んだら中では"
を使う。その逆も可。
# print(f'{d['key1']}, {d['key2']}')
# SyntaxError: invalid syntax
print(f"{d['key1']}, {d['key2']}")
# 10, 20
上述のように置換フィールド内ではバックスラッシュによるエスケープが使えないので注意。
# print(f'{d[\'key1\']}, {d[\'key2\']}')
# SyntaxError: f-string expression part cannot include a backslash
変数名とその値を同時に出力(Python3.8以降)
Python3.8から、置換フィールド{}
の変数名のあとに=
を書くと、変数名とその値が出力されるようになった。
i = 123
print(f'{i=}')
# i=123
変数名および=
の前後にスペースを置くと、結果にもそのまま出力される。
print(f'{i = }')
# i = 123
print(f'{ i = }')
# i = 123
コロン:
のあとに書式指定文字列を指定できる。また、変数単体だけでなく式の指定も可能。評価された値が出力される。
print(f'{i = :#b}')
# i = 0b1111011
print(f'{i * 2 = }')
# i * 2 = 246
リストや辞書に対しても同様。
l = [0, 10, 20]
print(f'{l = }, {l[1] = }')
# l = [0, 10, 20], l[1] = 10
d = {'key1': 10, 'key2': 20}
print(f'{d = }, {d["key1"] = }')
# d = {'key1': 10, 'key2': 20}, d["key1"] = 10