この記事では、Pythonで長すぎる文字列を文字数で分割したり、折り返ししたり、切り詰めたりする方法を解説します。
これらの処理を実装するには標準ライブラリのtextwrap
モジュールを使います。
Linktextwrap --- テキストの折り返しと詰め込み — Python 3.10.4 ドキュメント
それでは、サンプルを交えて使い方を見ていきましょう!
文字列を文字数で分割する
文字列を文字数で分割するには、textwrap
モジュールのwrap()
関数を使います。
textwrap.wrap(text, width=70, **kwargs)
width
引数を指定することで文字数を指定できます。
import textwrap
t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print(textwrap.wrap(t, width=10))
print(textwrap.wrap(t, width=20))
t = 'あいうえおかきくけこさしすせそ'
print(textwrap.wrap(t, width=5))
実行結果
['ABCDEFGHIJ', 'KLMNOPQRST', 'UVWXYZ']
['ABCDEFGHIJKLMNOPQRST', 'UVWXYZ']
['あいうえお', 'かきくけこ', 'さしすせそ']
**kwargs
引数には、TextWrapper
インスタンスの属性を指定することができます。
文字列を文字数で折り返す
文字列を文字数で折り返したい場合は、textwrap
モジュールのfill()
関数を使います。
textwrap.fill(text, width=70, **kwargs)
width
引数を指定することで文字数を指定できます。
import textwrap
t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
print(textwrap.fill(t, width=10))
print(textwrap.fill(t, width=20))
t = 'あいうえおかきくけこさしすせそ'
print(textwrap.fill(t, width=5))
実行結果
ABCDEFGHIJ
KLMNOPQRST
UVWXYZ
ABCDEFGHIJKLMNOPQRST
UVWXYZ
あいうえお
かきくけこ
さしすせそ
**kwargs
引数にはTextWrapper
インスタンスの属性を指定することができます。
文字数を超えた文字列を切り詰める
文字列を決まった文字数に切り詰めたい場合は、textwrap
モジュールのshorten()
関数を使います。
textwrap.shorten(text, width, **kwargs)
切り詰め時に使用される文字列の文字数もwidth
に含まれるので注意が必要です。
import textwrap
t = 'The first step is always the hardest.'
print(textwrap.shorten(t, width=15))
print(textwrap.shorten(t, width=20))
実行結果
The first [...]
The first step [...]
また、切り詰めが行われる箇所は「空白」なので文字列中に空白がない場合は以下のような結果になります。
t = 'Thefirststepisalwaysthehardest.'
print(textwrap.shorten(t, width=15))
print(textwrap.shorten(t, width=20))
実行結果
[...]
[...]
**kwargs
引数にはTextWrapper
インスタンスの属性を指定することができます。
大量に処理する場合はTextWrapperを使おう!
上記で紹介した関数たちは内部的にTextWrapper
インスタンスを生成して処理を行っています。
処理数が少ない場合はあまり気にする必要はありませんが、大量の文字列を処理する場合はTextWrapper
インスタンスを生成した方が処理が早くなります。
例えば、以下のコードは10万個の文字列をwrap()
関数を使って文字数で分割する速度を測っていますが、インスタンスを生成した方が早いことがわかります。
import textwrap
import time
# 時間を測る関数
def tic():
# require to import time
global start_time_tictoc
start_time_tictoc = time.time()
def toc(tag="elapsed time"):
if "start_time_tictoc" in globals():
print("{}: {:.9f} [sec]".format(tag, time.time() - start_time_tictoc))
else:
print("tic has not been called")
# 大量の文字列を生成
t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
texts = [t] * 100000
tic()
# インスタンスなし
for text in texts:
textwrap.wrap(text, width=20)
toc()
# TextWrapperインスタンスの生成
wrapper = textwrap.TextWrapper(width=20)
tic()
# インスタンスあり
for text in texts:
wrapper.wrap(text)
toc()
実行結果
elapsed time: 1.900254965 [sec]
elapsed time: 1.360962152 [sec]
インスタンス生成と属性代入のコストが無くなるとこれだけ早くなるんですね。
まとめ
文字列を文字数で分割したり、折り返ししたり、切り詰めたりする方法を解説しました。
区切り文字で分割したい場合は以下の記事を参照してください。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ