Skip to content

Python F-Strings: 文字列フォーマット完全ガイド

Updated on

文字列のフォーマットはPythonで最も一般的な操作の一つですが、長年にわたってフラストレーションの原因となってきました。「%」演算子はC言語から借用された分かりにくい書式コードを使用します。「.format()」メソッドは、テンプレート内で表示される位置から値を遠ざけて散在させます。「+」を使った文字列の結合は、型を手動で変換する必要があり、整理されず読みにくいコードを生み出します。すべてのアプローチは、値を文字列の中に入れるというシンプルなはずの作業に摩擦を加えているように感じられます。

実際のプロジェクトでは、この問題はさらに深刻になります。通貨を小数点以下2桁でフォーマットしたり、レポートの列を揃えたり、数字を先頭ゼロで埋めたり、パーセンテージを表示したり、タイムスタンプをフォーマットしたりする必要があります。それと同時に、コードの可読性も保たなければなりません。古い書式設定方法では、テンプレート文字列と引数リストという2つの並列した構造を維持する必要があります。順番を間違えると、エラーではなく間違った出力が生成され、すべてが静かに崩壊します。

Python 3.6では、f-string(書式付き文字列リテラル)が導入され、文字列のフォーマットは永遠に変わりました。文字列の前に「f」を付け、中括弧「{}」の中に式を直接埋め込むことで、f-stringは値を表示される位置の隣に保持します。他のあらゆる書式設定方法よりも高速です。完全な範囲の書式指定をサポートしています。そしてPython 3.8では、「=」指定子による組み込みのデバッグ機能が追加されました。このガイドでは、実用的で実行可能な例を交えながら、f-stringのすべての機能を解説します。

📚

f-stringとは?

f-stringは正式には「書式付き文字列リテラル」と呼ばれ、PEP 498 (opens in a new tab)で導入され、Python 3.6でリリースされました。概念はシンプルです。任意の文字列の前に「f」(または「F」)を付けると、Pythonは実行時に中括弧「{}」内の式を評価し、結果を文字列に変換して出力に挿入します。

name = "Alice"
age = 30
 
greeting = f"My name is {name} and I am {age} years old."
print(greeting)
# Output: My name is Alice and I am 30 years old.

「f」プレフィックスはシングルクォート、ダブルクォート、トリプルクォートで機能します:

single = f'Hello, {name}'
double = f"Hello, {name}"
triple_double = f"""Hello, {name}"""
triple_single = f'''Hello, {name}'''

内部的には、Pythonはf-stringをパース時に一連の文字列連結と「format()」操作にコンパイルします。これが、f-stringが「.format()」を自分で呼び出すよりも高速な理由です。インタープリータが操作を直接最適化するからです。

基本的なf-string構文

コアとなる構文は簡単です:f"テキスト {式} さらなるテキスト"と書きます。Pythonは式を評価し、結果に対して「str()」を呼び出し、それを文字列に挿入します。

# Variables
city = "Tokyo"
population = 13960000
 
print(f"{city} has a population of {population}.")
# Output: Tokyo has a population of 13960000.
 
# You can use either f or F
print(F"Welcome to {city}!")
# Output: Welcome to Tokyo!

単一のf-string内に任意の数の式を配置できます:

first = "Grace"
last = "Hopper"
title = "Rear Admiral"
year = 1906
 
bio = f"{title} {first} {last}, born {year}, lived to {1992 - year} years."
print(bio)
# Output: Rear Admiral Grace Hopper, born 1906, lived to 86 years.

f-string内の式

f-stringは変数を挿入するだけでなく、中括弧の間にあらゆる有効なPython式を評価します。これには算術演算、メソッド呼び出し、関数呼び出し、三項演算子、リストのインデックス指定、辞書へのアクセスなどが含まれます。

算術と数学

x = 15
y = 4
 
print(f"{x} + {y} = {x + y}")
print(f"{x} / {y} = {x / y:.2f}")
print(f"{x} ** {y} = {x ** y}")
print(f"{x} % {y} = {x % y}")
# Output:
# 15 + 4 = 19
# 15 / 4 = 3.75
# 15 ** 4 = 50625
# 15 % 4 = 3

メソッド呼び出し

text = "  hello, python world  "
 
print(f"Stripped: '{text.strip()}'")
print(f"Title case: '{text.strip().title()}'")
print(f"Upper: '{text.strip().upper()}'")
print(f"Replace: '{text.strip().replace('python', 'f-string')}'")
# Output:
# Stripped: 'hello, python world'
# Title case: 'Hello, Python World'
# Upper: 'HELLO, PYTHON WORLD'
# Replace: 'hello, f-string world'

関数呼び出し

def calculate_bmi(weight_kg, height_m):
    return weight_kg / (height_m ** 2)
 
weight = 70
height = 1.75
 
print(f"BMI: {calculate_bmi(weight, height):.1f}")
# Output: BMI: 22.9
 
# Built-in functions
items = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"Items: {items}")
print(f"Count: {len(items)}, Sum: {sum(items)}, Min: {min(items)}, Max: {max(items)}")
# Output:
# Items: [3, 1, 4, 1, 5, 9, 2, 6]
# Count: 8, Sum: 31, Min: 1, Max: 9

三項(条件)演算子

score = 85
status = f"Result: {'PASS' if score >= 60 else 'FAIL'}"
print(status)
# Output: Result: PASS
 
temperature = -5
print(f"Water is {'frozen' if temperature <= 0 else 'liquid' if temperature < 100 else 'steam'}.")
# Output: Water is frozen.

辞書とリストへのアクセス

user = {"name": "Bob", "role": "engineer", "level": 3}
scores = [88, 92, 76, 95, 81]
 
print(f"{user['name']} is a level {user['level']} {user['role']}.")
# Output: Bob is a level 3 engineer.
 
print(f"First score: {scores[0]}, Last score: {scores[-1]}")
# Output: First score: 88, Last score: 81

書式指定:数字、揃え、パディング

f-stringの真の力は書式指定にあります。式の後にコロン「:」を追加し、続けて書式指定を記述します。一般的な構文は以下の通りです:

{式:[[fill]align][sign][#][0][width][grouping_option][.precision][type]}

これは複雑に見えますが、各部分はオプションです。例を交えて分解していきましょう。

小数点以下の桁数と浮動小数点の精度

「.Nf」指定子は、floatが表示する小数点以下の桁数を制御します:

pi = 3.141592653589793
 
print(f"Default:    {pi}")
print(f"2 decimals: {pi:.2f}")
print(f"4 decimals: {pi:.4f}")
print(f"0 decimals: {pi:.0f}")
print(f"8 decimals: {pi:.8f}")
# Output:
# Default:    3.141592653589793
# 2 decimals: 3.14
# 4 decimals: 3.1416
# 0 decimals: 3
# 8 decimals: 3.14159265

桁区切り

大きな数字は、コンマまたはアンダースコアによるグループ化ですぐに読みやすくなります:

revenue = 1234567890
small_amount = 1234.5
 
print(f"Revenue: {revenue:,}")
print(f"Revenue: {revenue:_}")
print(f"Amount: ${small_amount:,.2f}")
# Output:
# Revenue: 1,234,567,890
# Revenue: 1_234_567_890
# Amount: $1,234.50

パーセンテージの書式設定

「%」型は値を100倍し、パーセント記号を付加します:

completion = 0.876
error_rate = 0.034
growth = 1.25
 
print(f"Completion: {completion:.1%}")
print(f"Error rate: {error_rate:.2%}")
print(f"Growth: {growth:.0%}")
# Output:
# Completion: 87.6%
# Error rate: 3.40%
# Growth: 125%

指数表記

avogadro = 6.022e23
planck = 6.626e-34
 
print(f"Avogadro: {avogadro:.3e}")
print(f"Planck: {planck:.4E}")
# Output:
# Avogadro: 6.022e+23
# Planck: 6.6260E-34

整数の基数:2進数、8進数、16進数

value = 255
 
print(f"Decimal:     {value:d}")
print(f"Binary:      {value:b}")
print(f"Octal:       {value:o}")
print(f"Hex (lower): {value:x}")
print(f"Hex (upper): {value:X}")
print(f"With prefix: {value:#b}  {value:#o}  {value:#x}")
# Output:
# Decimal:     255
# Binary:      11111111
# Octal:       377
# Hex (lower): ff
# Hex (upper): FF
# With prefix: 0b11111111  0o377  0xff

揃えとパディング

揃え指定子は、指定された幅の中で値をどのように配置するかを制御します。左揃えには「<」、右揃えには「>」、中央揃えには「^」を使用します:

label = "Python"
 
print(f"|{label:<20}|")   # Left-align in 20 chars
print(f"|{label:>20}|")   # Right-align
print(f"|{label:^20}|")   # Center
print(f"|{label:*^20}|")  # Center with * fill
print(f"|{label:->20}|")  # Right with - fill
# Output:
# |Python              |
# |              Python|
# |       Python       |
# |*******Python*******|
# |--------------Python|

レポートの書式設定では、数字のゼロ埋めが一般的です:

for i in [1, 42, 100, 7, 999]:
    print(f"ID: {i:05d}")
# Output:
# ID: 00001
# ID: 00042
# ID: 00100
# ID: 00007
# ID: 00999

揃えたテーブルの構築

揃えと書式指定を組み合わせることで、整ったテーブルが作成できます:

products = [
    ("Laptop Pro", 1299.99, 45),
    ("Wireless Mouse", 29.50, 230),
    ("USB-C Hub", 54.95, 120),
    ("Monitor 27in", 449.00, 67),
]
 
print(f"{'Product':<18} {'Price':>10} {'Stock':>7}")
print("-" * 37)
for name, price, stock in products:
    print(f"{name:<18} ${price:>9.2f} {stock:>7,}")
print("-" * 37)
 
total_value = sum(p * s for _, p, s in products)
print(f"{'Total Value':<18} ${total_value:>9,.2f}")
 
# Output:
# Product               Price   Stock
# -------------------------------------
# Laptop Pro         $ 1,299.99      45
# Wireless Mouse     $    29.50     230
# USB-C Hub          $    54.95     120
# Monitor 27in       $   449.00      67
# -------------------------------------
# Total Value        $91,498.05

f-stringを使った日付と時刻の書式設定

f-stringはstrftime書式コードを直接受け付けるため、「datetime」オブジェクトを「.strftime()」を呼び出さずに書式設定できます:

from datetime import datetime, date, timedelta
 
now = datetime.now()
 
print(f"ISO format:  {now:%Y-%m-%d %H:%M:%S}")
print(f"US format:   {now:%m/%d/%Y}")
print(f"Long format: {now:%B %d, %Y at %I:%M %p}")
print(f"Day of week: {now:%A}")
print(f"Short month: {now:%b %d}")
# Output (varies by current time):
# ISO format:  2026-02-13 14:30:00
# US format:   02/13/2026
# Long format: February 13, 2026 at 02:30 PM
# Day of week: Friday
# Short month: Feb 13

これは「date」オブジェクトでも機能します:

from datetime import date
 
birthday = date(1995, 8, 15)
today = date.today()
age_days = (today - birthday).days
 
print(f"Birthday: {birthday:%B %d, %Y}")
print(f"Days alive: {age_days:,}")
print(f"Years (approx): {age_days / 365.25:.1f}")
# Output:
# Birthday: August 15, 1995
# Days alive: 11,139
# Years (approx): 30.5

複数行のf-string

トリプルクォートのf-stringを使用すると、書式設定されたテキストブロックを構築できます。トリプルクォートf-stringの各行は「{}」式を含むことができます:

project = "Data Pipeline"
owner = "Engineering Team"
status = "In Progress"
completion = 0.73
budget = 250000
spent = 182500
 
report = f"""
========================================
  Project Status Report
========================================
  Project:    {project}
  Owner:      {owner}
  Status:     {status}
  Completion: {completion:.0%}
  Budget:     ${budget:>12,}
  Spent:      ${spent:>12,}
  Remaining:  ${budget - spent:>12,}
========================================
"""
 
print(report)

また、暗黙の文字列連結(演算子なしで隣り合わせて配置)を使用して複数のf-stringを連結することで、複数行のf-stringを構築することもできます:

name = "Alice"
role = "Data Scientist"
years = 5
 
bio = (
    f"Name: {name}\n"
    f"Role: {role}\n"
    f"Experience: {years} years\n"
    f"Seniority: {'Senior' if years >= 5 else 'Mid-level'}"
)
 
print(bio)
# Output:
# Name: Alice
# Role: Data Scientist
# Experience: 5 years
# Seniority: Senior

この2番目のアプローチは、トリプルクォート文字列で時々発生する先頭の改行とインデントの問題を回避します。

デバッグ用の=指定子(Python 3.8+)

Python 3.8では、f-stringに「=」指定子が追加されました。これは言語で最も有用なデバッグ機能の一つです。「f"{expression=}"」と書くと、Pythonは式のテキストとその値の両方を出力します。

x = 42
y = 17
 
print(f"{x=}")
print(f"{y=}")
print(f"{x + y=}")
print(f"{x * y=}")
# Output:
# x=42
# y=17
# x + y=59
# x * y=714

「=」は書式指定子と組み合わせることができます:

price = 49.99
tax_rate = 0.0825
total = price * (1 + tax_rate)
 
print(f"{price=:.2f}")
print(f"{tax_rate=:.1%}")
print(f"{total=:.2f}")
# Output:
# price=49.99
# tax_rate=8.2%
# total=54.12

「=」指定子はその周囲の空白を保持します。「=」の前にスペースを追加すると出力が整形されます:

name = "Alice"
score = 95
 
print(f"{name = }")
print(f"{score = }")
# Output:
# name = 'Alice'
# score = 95

文字列では、「=」はデフォルトで「repr()」を使用します(クォートを表示)。数字では「str()」を使用します。

複雑な式のデバッグ

「=」指定子はあらゆる式で機能し、中間値を確認するための高速な方法となります:

data = [23, 45, 12, 67, 34, 89, 56]
 
print(f"{len(data)=}")
print(f"{sum(data)=}")
print(f"{sum(data)/len(data)=:.2f}")
print(f"{sorted(data)=}")
print(f"{max(data) - min(data)=}")
# Output:
# len(data)=7
# sum(data)=326
# sum(data)/len(data)=46.57
# sorted(data)=[12, 23, 34, 45, 56, 67, 89]
# max(data) - min(data)=77

Jupyter Notebookで作業していて、デバッグ中に常に「print(f"{variable=}")」の呼び出しを追加している自分に気づいた場合は、RunCell (opens in a new tab)を検討してください。Jupyter内で直接実行されるAIエージェントです。RunCellはNotebookのメモリ内の変数を理解し、手動でデバッグ文を書くことなく、変数を検査、説明、修正を提案することができます。複数のセルにわたって中間値を検証する必要があるデータ変換をステップスルーする際に特に有用です。

ネストされたf-string

f-stringの中にf-stringをネストすることができます。最も一般的なユースケースは、幅や精度が変数から来る動的な書式指定です:

# Dynamic precision
value = 3.14159265
for precision in range(1, 6):
    print(f"  {precision} decimals: {value:.{precision}f}")
# Output:
#   1 decimals: 3.1
#   2 decimals: 3.14
#   3 decimals: 3.142
#   4 decimals: 3.1416
#   5 decimals: 3.14159
# Dynamic width
header = "Report"
for width in [20, 30, 40]:
    print(f"|{header:^{width}}|")
# Output:
# |       Report       |
# |            Report            |
# |                 Report                 |
# Nested f-string for formatting a list
values = [1.234, 56.789, 0.001, 999.999]
decimals = 2
formatted = f"Results: {', '.join(f'{v:.{decimals}f}' for v in values)}"
print(formatted)
# Output: Results: 1.23, 56.79, 0.00, 1000.00

ネストは控えめに使用してください。f-stringが1レベル以上のネストを必要とする場合は、内部のロジックを変数または関数に抽出して可読性を高めてください。

他の文字列書式設定方法との比較

Pythonには文字列書式設定のための4つの主要なアプローチがあります。以下に直接比較を示します:

機能f-string f"...{x}...".format() "...{}...".format(x)% 演算子 "...%s..." % xTemplate Template("...$x...")
Pythonバージョン3.6+2.6+すべてすべて
可読性優秀 -- 値がインライン良好 -- 番号付き/名前付きプレースホルダー普通 -- 位置指定コード良好 -- 名前付きプレースホルダー
パフォーマンス最速約1.5-2倍遅い約1.3-1.8倍遅い最も遅い
任意の式限定不可不可
デバッグ指定子 (=)可 (3.8+)不可不可不可
再利用可能なテンプレート不可
ユーザー入力に安全不可不可不可可 (safe_substitute)
型の書式設定完全完全一部なし
name = "Charlie"
balance = 1234.56
 
# f-string (recommended)
print(f"{name} has ${balance:,.2f}")
 
# .format()
print("{} has ${:,.2f}".format(name, balance))
 
# % formatting
print("%s has $%,.2f" % (name, balance))  # Note: %  does not support comma grouping
 
# Template (from string module)
from string import Template
t = Template("$name has $balance")
print(t.substitute(name=name, balance=f"${balance:,.2f}"))

いつどれを使用するか:

  • f-string: Python 3.6+を実行している場合のデフォルトの選択。
  • .format(): 変数や設定ファイルに格納される再利用可能なテンプレートが必要な場合に使用。
  • % formatting: レガシーコードのみ。新規プロジェクトで使用する理由はない。
  • Template: 書式指定文字列が信頼できないユーザー入力から来る場合に使用(任意の式を実行できない)。

パフォーマンス比較

f-stringは、パース時に最適化されたバイトコードにコンパイルされ、「.format()」や「%」に必要なメソッド呼び出しと引数解析のオーバーヘッドを回避するため、高速です。

import timeit
 
name = "Alice"
age = 30
score = 95.5
 
# Benchmark each method with 1 million iterations
fstring_time = timeit.timeit(
    'f"{name} scored {score:.1f} at age {age}"',
    globals={"name": name, "age": age, "score": score},
    number=1_000_000
)
 
format_time = timeit.timeit(
    '"{} scored {:.1f} at age {}".format(name, score, age)',
    globals={"name": name, "age": age, "score": score},
    number=1_000_000
)
 
percent_time = timeit.timeit(
    '"%s scored %.1f at age %d" % (name, score, age)',
    globals={"name": name, "age": age, "score": score},
    number=1_000_000
)
 
concat_time = timeit.timeit(
    'name + " scored " + str(score) + " at age " + str(age)',
    globals={"name": name, "age": age, "score": score},
    number=1_000_000
)
 
print(f"f-string:      {fstring_time:.4f}s (baseline)")
print(f"str.format():  {format_time:.4f}s ({format_time/fstring_time:.2f}x slower)")
print(f"% formatting:  {percent_time:.4f}s ({percent_time/fstring_time:.2f}x slower)")
print(f"concatenation: {concat_time:.4f}s ({concat_time/fstring_time:.2f}x slower)")
 
# Typical results:
# f-string:      0.0850s (baseline)
# str.format():  0.1450s (1.71x slower)
# % formatting:  0.1100s (1.29x slower)
# concatenation: 0.1200s (1.41x slower)

式が複雑になるほど、パフォーマンスの差は広がります。数千のレコードを処理するタイトなループでは、f-stringは測定可能な違いをもたらします。

よくある間違いと注意点

中括弧のエスケープ

f-stringにリテラルの「{」または「}」を含めるには、それを2倍します:

value = 42
 
# Literal braces around a value
print(f"{{{value}}}")
# Output: {42}
 
# JSON-like output
key = "name"
val = "Alice"
print(f'{{"{key}": "{val}"}}')
# Output: {"name": "Alice"}
 
# Just literal braces, no interpolation
print(f"Use {{variable}} syntax in f-strings")
# Output: Use {variable} syntax in f-strings

式内のバックスラッシュ

f-stringの「{}」式の部分内ではバックスラッシュ文字を使用できません。これは可読性のための意図的な設計上の選択です:

items = ["apple", "banana", "cherry"]
 
# This causes a SyntaxError:
# print(f"{'\\n'.join(items)}")
 
# Solution 1: assign to a variable first
newline = "\n"
print(f"{newline.join(items)}")
 
# Solution 2: use a separate operation
joined = "\n".join(items)
print(f"Items:\n{joined}")
 
# Solution 3: use chr()
print(f"{chr(10).join(items)}")

クォートの競合

f-stringがダブルクォートを使用する場合、内部の式はシングルクォートを使用する必要があります(またはその逆):

data = {"name": "Alice", "age": 30}
 
# Use single quotes inside when f-string uses double quotes
print(f"Name: {data['name']}, Age: {data['age']}")
 
# Or use double quotes inside when f-string uses single quotes
print(f'Name: {data["name"]}, Age: {data["age"]}')
 
# With triple quotes, you have more flexibility
print(f"""Name: {data["name"]}, Age: {data["age"]}""")

f-stringは定数ではない

f-stringは実行時に評価されるため、デフォルトの引数値やランタイム状態に依存するモジュールレベルの定数として使用することはできません:

# This works but evaluates at call time, not definition time
def greet(name, template=None):
    if template is None:
        template = f"Hello, {name}!"  # Evaluated here
    return template
 
# For true templates, use str.format()
TEMPLATE = "Hello, {name}! You have {count} messages."
print(TEMPLATE.format(name="Alice", count=5))

大きな式に注意

f-stringにあらゆる式を入れられるからといって、すべきだという意味ではありません。f-stringの式はシンプルに保ちましょう:

# Hard to read -- too much logic inside the f-string
result = f"{'%.2f' % (sum(x**2 for x in range(100)) / 100)}"
 
# Much better -- compute first, then format
mean_square = sum(x**2 for x in range(100)) / 100
result = f"{mean_square:.2f}"

Raw f-string

「r」(raw)と「f」プレフィックスを組み合わせると、バックスラッシュがリテラルとして扱われ(エスケープシーケンスなし)、式はまだ評価されるraw f-stringが作成されます:

user = "admin"
folder = "projects"
 
# Raw f-string for Windows paths
path = rf"C:\Users\{user}\{folder}\data.csv"
print(path)
# Output: C:\Users\admin\projects\data.csv
 
# Useful for regex patterns with dynamic parts
import re
prefix = "user"
pattern = rf"\b{prefix}_\d+\b"
text = "Found user_123 and user_456 in the log"
matches = re.findall(pattern, text)
print(f"Matches: {matches}")
# Output: Matches: ['user_123', 'user_456']

「rf"..."」と「fr"..."」の両方が有効です。プレフィックスの順序は関係ありません。

データサイエンスワークフローでのf-string

f-stringは、出力の書式設定、動的なラベルの構築、数値結果からの読みやすいサマリーの作成において、データサイエンスにとって不可欠です。

数値出力の書式設定

import statistics
 
data = [23.4, 45.1, 31.8, 52.3, 41.7, 38.9, 29.6, 47.2]
 
mean = statistics.mean(data)
median = statistics.median(data)
stdev = statistics.stdev(data)
cv = stdev / mean  # coefficient of variation
 
print(f"Sample size:    {len(data)}")
print(f"Mean:           {mean:.2f}")
print(f"Median:         {median:.2f}")
print(f"Std deviation:  {stdev:.2f}")
print(f"CV:             {cv:.1%}")
print(f"Range:          {min(data):.1f} - {max(data):.1f}")
# Output:
# Sample size:    8
# Mean:           38.75
# Median:         40.30
# Std deviation:  9.87
# CV:             25.5%
# Range:          23.4 - 52.3

Pandas DataFrameでの作業

import pandas as pd
 
df = pd.DataFrame({
    "product": ["Widget A", "Widget B", "Widget C", "Widget D"],
    "revenue": [125000, 89000, 234000, 67000],
    "units": [1250, 2100, 980, 3400],
})
 
# Summary statistics with f-strings
total_rev = df["revenue"].sum()
avg_price = (df["revenue"] / df["units"]).mean()
 
print(f"Total Revenue:  ${total_rev:>12,}")
print(f"Avg Unit Price: ${avg_price:>12,.2f}")
print(f"Products:       {len(df):>12,}")
 
# Dynamic column formatting
for _, row in df.iterrows():
    unit_price = row["revenue"] / row["units"]
    print(f"  {row['product']:<12} | Revenue: ${row['revenue']:>9,} | Units: {row['units']:>5,} | $/unit: ${unit_price:.2f}")
 
# Output:
# Total Revenue:  $     515,000
# Avg Unit Price: $       56.00
# Products:              4
#   Widget A     | Revenue: $  125,000 | Units: 1,250 | $/unit: $100.00
#   Widget B     | Revenue: $   89,000 | Units: 2,100 | $/unit: $42.38
#   Widget C     | Revenue: $  234,000 | Units:   980 | $/unit: $238.78
#   Widget D     | Revenue: $   67,000 | Units: 3,400 | $/unit: $19.71

テキストのサマリーを超えてデータ分析を行い、インタラクティブな探索が必要な場合は、PyGWalker (opens in a new tab)を使用すると、単一行のコードで任意のpandas DataFrameをTableauのようなインタラクティブな可視化に変換できます。静的なレポート用に数字を手動でフォーマットする代わりに、ドラッグアンドドロップでチャートを構築し、フィルタを適用し、視覚的にパターンを探索できます。すべてJupyter Notebook内で行えます。

import pandas as pd
import pygwalker as pyg
 
# After preparing your DataFrame with well-formatted columns
df = pd.DataFrame({
    "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "Revenue": [125000, 134000, 158000, 142000, 167000, 189000],
    "Growth": [0.05, 0.072, 0.179, -0.101, 0.176, 0.132],
})
 
# Add formatted columns for display
df["Revenue_Display"] = df["Revenue"].apply(lambda x: f"${x:,.0f}")
df["Growth_Display"] = df["Growth"].apply(lambda x: f"{x:+.1%}")
 
# Launch interactive visualization
# pyg.walk(df)

モデル結果の書式設定

# Formatting machine learning results
metrics = {
    "accuracy": 0.9234,
    "precision": 0.8891,
    "recall": 0.9456,
    "f1_score": 0.9164,
    "auc_roc": 0.9678,
}
 
print("Model Evaluation Results")
print("=" * 35)
for metric, value in metrics.items():
    bar_length = int(value * 20)
    bar = "#" * bar_length + "-" * (20 - bar_length)
    print(f"  {metric:<12} {value:.4f}  [{bar}]")
# Output:
# Model Evaluation Results
# ===================================
#   accuracy     0.9234  [##################--]
#   precision    0.8891  [#################---]
#   recall       0.9456  [##################--]
#   f1_score     0.9164  [##################--]
#   auc_roc      0.9678  [###################-]

変換フラグ:!s、!r、!a

f-stringは、式の値が書式設定される前にどのように変換されるかを制御する3つの変換フラグをサポートしています:

  • 「!s」は値に対して「str()」を呼び出します(デフォルトの動作)
  • 「!r」は値に対して「repr()」を呼び出します
  • 「!a」は値に対して「ascii()」を呼び出します
text = "Hello\tWorld"
name = "Caf\u00e9"
 
print(f"str:   {text!s}")
print(f"repr:  {text!r}")
print(f"ascii: {name!a}")
# Output:
# str:   Hello	World
# repr:  'Hello\tWorld'
# ascii: 'Caf\xe9'

「!r」フラグは、クォートやエスケープ文字を含む生の表現を表示するため、デバッグに特に有用です。「=」指定子とうまく組み合わせて機能します。

よくある質問

Pythonのf-stringとは何ですか?いつ導入されましたか?

f-string(書式付き文字列リテラル)は、PEP 498を通じてPython 3.6で導入された文字列書式設定メカニズムです。文字列の前に「f」を付け、中括弧の中に式を配置することで、Python式を文字列リテラル内に直接埋め込むことができます。f-stringは実行時に評価され、すべての書式設定オプションの中で最高の可読性を提供し、パース時に最適化されたバイトコードにコンパイルされるため「str.format()」や「%」書式設定よりも高速です。

f-stringでカンマと小数点以下の桁数を使って数字を書式設定するにはどうすればよいですか?

中括弧内のコロンの後に書式指定を使用します。桁区切りとしてカンマを使用するには、「:,」を使用します。例えば、f"{1234567:,}"は「"1,234,567"」を生成します。小数点以下の桁数には、「:.Nf」を使用します(Nは桁数)。例えば、f"{3.14159:.2f}"は「"3.14"」を生成します。両方を組み合わせるには、f"{1234.5:,.2f}"とすると「"1,234.50"」が出力されます。パーセンテージには、「:.N%」を使用します。これは100倍してパーセント記号を付加します:f"{0.85:.1%}"は「"85.0%"」を生成します。

f-stringの=指定子とは何ですか?デバッグにどのように役立ちますか?

「=」指定子はPython 3.8で追加され、式のテキストとその値の両方を出力します。「f"{variable=}"」と書くと、「variable=value」と出力されます。これにより、デバッグ時に変数名を2回入力する必要がなくなります。あらゆる式で機能します:f"{len(data)=}"は「len(data)=42」と出力されます。書式指定子と組み合わせることもできます:f"{price=:.2f}"は「price=49.99」と出力されます。

複数行文字列でf-stringを使用できますか?

はい。トリプルクォート(f"""..."""またはf'''...''')を使用して複数行のf-stringを作成します。各行は「{expression}」プレースホルダーを含むことができます。または、暗黙の文字列連結を使用して、括弧内で隣り合わせて配置することで複数のf-stringを連結することもできます。

f-stringはstr.format()や%書式設定よりも高速ですか?

はい。f-stringは一貫してPythonで最も高速な文字列書式設定方法です。ベンチマークでは、通常「str.format()」より1.5〜2倍、「%」書式設定より1.3〜1.8倍高速です。速度の利点は、Pythonがf-stringを実行時のメソッド検索や引数解析ではなく、効率的なバイトコードに直接変換するコンパイル時の最適化から来ています。

f-stringにリテラルの中括弧を含めるにはどうすればよいですか?

中括弧を2倍します。リテラルの「{」には「{{」を、リテラルの「}」には「}}」を使用します。例えば、f"{{value}}"はプレーンテキストで「{value}」を出力します。補間された値を中括弧で囲むには、f"{{{variable}}}"を使用します。外側の2倍の中括弧はリテラルの中括弧を生成し、内側の単一の中括弧は補間をトリガーします。

まとめ

f-stringは、現代のPythonで文字列を書式設定するための標準的な方法です。あらゆる書式設定アプローチの中で最高の可読性と最高のパフォーマンスを組み合わせ、小数点以下の精度、桁区切り、パーセンテージ、指数表記、揃え、パディング、日付の書式設定、基数変換の完全な範囲の書式指定をサポートしています。

覚えておくべき重要な点:

  • 「f」を前に付け、中括弧「{}」の中に式を入れます。
  • コロンの後に書式指定を使用して出力を精密に制御します(:.2f:,:.1%:<20)。
  • デバッグには式の後に「=」を使用します(「f"{variable=}"」)。Python 3.8+が必要です。
  • リテラルの中括弧は2倍してエスケープします:「{{」と「}}」。
  • {}」の中にバックスラッシュを入れないでください。最初に変数に代入してください。
  • 式はシンプルに保ちます。「{}」の中のロジックが読みにくい場合は、抽出してください。
  • 変数に格納される再利用可能なテンプレートが必要な場合のみ「.format()」を使用します。

f-stringは、クイックな「print()」デバッグから本番のレポート生成まで、あらゆるものを処理します。一度採用すれば、古い書式設定方法に戻る理由はありません。データパイプラインの構築、MLモデル出力の書式設定、財務レポートの生成など、どのような作業でも、f-stringはクリーンで高速で読みやすいコードを提供します。

📚