Pythonのtextwrap.dedent()
メソッドを使うと、インデントされたテキストのインデントを除去して整形できます。
環境
- Python 3.10.12
- Google Colaboratory(Colab)
Pythonでヒアドキュメントにインデントが入ってしまって困る
ヒアドキュメントで複数行に渡るテキストを書く時などは、インデントがぐちゃぐちゃになりがちです。特にPythonはインデントが重要なので、文法上問題は無くても気になります。
def f1():
# 適当なテキスト
text = """
これはサンプルテキストであり、実際に意味はありません。
- あなたは優秀なアシスタントです
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください
"""
return text
LLMを使うアプリとかだと、promptを指定するために上記のようなコードを書く時はあると思います。
sample_text = f1()
print(sample_text)
あなたは優秀なアシスタントです。
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください
- これはサンプルテキストであり、実際に意味はありません
Pythonソースコードのインデントが文字列の中に入ってしまいます。LLMだったらこれでもだいたい問題なく動くんですが、トークンも無駄ですしイケてないです。
無駄なスペースの無い文字列にしようとすると、ソースコードとしての見た目が残念な感じになります。
def f2():
# 適当なテキスト
text = """これはサンプルテキストであり、実際に意味はありません。
- あなたは優秀なアシスタントです
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください"""
return text
Pythonの文法上は問題無いんですが、見た目のインデントも大切にしたいですね。
dedent
を使う
text の各行に対し、共通して現れる先頭の空白を削除します。
textwrap.dedent
を使うと、インデントの付いた文字列をきれいにできます。
from textwrap import dedent
print(dedent(sample_text))
これはサンプルテキストであり、実際に意味はありません。
- あなたは優秀なアシスタントです
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください
strip()
も使って先頭と末尾の空白文字を除去するのが良いと思います。
def clean_text(text: str) -> str:
return dedent(text).strip()
print(clean_text(sample_text))
これはサンプルテキストであり、実際に意味はありません。
- あなたは優秀なアシスタントです
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください
これで、Pythonのソースコード上のインデントの見た目を保ったまま、文字列から不要なインデントを取り除けました。
dedent
を書式指定文字列と併用する
textwrap.dedent()
とフォーマット済み文字列リテラル(f-string)と併用すると、埋め込んだ文字列も複数行にまたがるような時にうまくインデントを除去できません。
def f3(input_text: str):
return_text = f"""
こんにちは、{input_text}さん。
今日もよろしくお願いします。
"""
return clean_text(return_text)
input_text = clean_text("""
グレートブリテン及び
北アイルランド連合王国
""")
print(f3(input_text))
こんにちは、グレートブリテン及び
北アイルランド連合王国さん。
今日もよろしくお願いします。
これはフォーマット済み文字列リテラルではなくformat()
を使ってdedent()
の後にフォーマットすれば解決できます。
def f4(input_text: str):
return_text = """
こんにちは、{input_text}さん。
今日もよろしくお願いします。
"""
return clean_text(return_text).format(input_text=input_text)
input_text = clean_text("""
グレートブリテン及び
北アイルランド連合王国
""")
print(f4(input_text))
こんにちは、グレートブリテン及び
北アイルランド連合王国さん。
今日もよろしくお願いします。
余談
Rubyのヒアドキュメントは、~
を使って書くことでインデントが除去されます。
def f
return <<~EOS
これはサンプルテキストであり、実際に意味はありません。
- あなたは優秀なアシスタントです
- すべての質問に関西弁で答えてください
- コテコテでお願いします
- 3行以内で簡潔に答えてください
EOS
end