2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonでdedent()を使うと文字列のインデントを取り除ける

Posted at

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のヒアドキュメントは、~を使って書くことでインデントが除去されます。

Ruby
def f
  return <<~EOS
    これはサンプルテキストであり、実際に意味はありません。
    - あなたは優秀なアシスタントです
    - すべての質問に関西弁で答えてください
      - コテコテでお願いします
    - 3行以内で簡潔に答えてください
  EOS
end
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?