トップページに戻る

文字列操作(1)str.format

本記事では、Python3.6以降で導入された機能も紹介しています。
特別な理由がなければ、Python3.6以降の新しいバージョンを使用することをおすすめします。

目次

  • Pythonにおける文字列(string型)
  • 文字列の結合
    • +を使った結合
    • str.format関数
      • 基本的な使い方
      • (気になる人向け)書式指定子の構造
    • f-string

Pythonにおける文字列(string型)

Pythonで文字列を扱うための組み込みクラスとして、stringという型があります。別の言い方として、文字列型strなどと呼ばれることもあります。
大概の文字列操作はこのクラスだけで出来ちゃうので、マスターするとファイル入出力などで困ることがぐっと減ります。数値をフォーマットして文字列に変換したり、必要な部分を抜き出したり、特定文字を区切り文字として複数の文字列に分割したりと多機能なクラスです。
文字列は"(ダブルクォーテーション)もしくは'(シングルクォーテーション)で囲むことで作れます(2つの違いはまったくない)。

In [1]:
s = "hello"
# s = 'hello' <-- これでもよい
type(s)
Out[1]:
str

CでのcharやFortranでのcharacterと違い、文字そのものも長さが1の文字列として扱います。事前に配列を定義する必要があったり、結合しているうちに最初に定義した配列サイズを超えるといったことはなく、直感的な操作が可能です。

In [2]:
len("a")
Out[2]:
1

文字列の結合

+記号を使った文字列の結合

多くのスクリプト言語と同様に、文字列を結合するためには+記号を使います。

In [3]:
# +記号を使った文字列の結合
"hello" + "," + "world" # --> 'hello,world'

# +を使わずこんな結合もできる
"hello"",""world" # --> 'hello,world'
Out[3]:
'hello,world'

ここで一つ注意しなければならないのは、intfloatといった数値の型はstring型と「+」を用いた結合ができないということです。数値をstring型と結合するためには、数値をstring型に明示的にキャスト(型の変換)する必要があります。

In [4]:
# 1 + "a" #TypeError
str(1) + "a"
Out[4]:
'1a'

このような少し面倒な仕様になっているのは、意図していない結合をした場合に必ずエラーが出るようにするためです。
CやFortranのように型を事前に指定して変数を定義するコンパイル言語と違い、Pythonを始めとしたスクリプト言語では、変数に異なる型を代入できるために、間違った型を入れたままコードを書いてしまうことがあります。
一例を上げると、

In [5]:
num1 = 1
num2 = "3" #ファイルからの読み取りの際、stringのままに変数に保存
num1 + num2 #TypeError
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-63084913d688> in <module>()
      1 num1 = 1
      2 num2 = "3" #ファイルからの読み取りの際、stringのままに変数に保存
----> 3 num1 + num2 #TypeError

TypeError: unsupported operand type(s) for +: 'int' and 'str'

このコードを書いた人は最後の行では何をしようとしたのでしょうか?可能性は2つあります。

  • num1, num2のどちらもstringだと思って計算し、出力では「13」を出そうとした
  • num1, num2のどちらもintだと思って計算し、出力では「4」を出そうとした

もちろん、Pythonのインタプリタ(コードを一行ごと読み込んで実行するもの)はどちらが本来意図されていたかを知る由もないのでエラーを吐き出すわけです。
この面倒な仕様は、スクリプト言語の宿命とも言える産物なのです。

str.format関数

上記のような宿命は納得したとしても、さすがに毎回キャストするのは面倒です。 2つの文字列を結合するぐらいならキャストでいいかもしれませんが、大抵の場合、もっと多くの文字列を結合したいはずなので、これを簡単にする関数としてstr.formatが用意されています。
複数の文字列、数値などを連結する場合に非常によく使います。特に、科学技術計算などで数値をフォーマット(桁数を指定するなど)する際に役立ちます。
生の文字列もstringなので、実は関数を呼び出すことができ、format関数を使うときには大抵このように記述します。

In [6]:
"正の整数で一番小さいものは、「{}」".format(1)
Out[6]:
'正の整数で一番小さいものは、「1」'

基本的にformat関数は、文字列中の「{ }」の場所に、引数をstringにキャストして埋め込むという機能を持ちます。
formatの引数は複数入れることも可能で、その場合、引数の個数に対応した「{}」を文字列の中に含んでいなければなりません。

In [7]:
num1 = 1
num2 = 3
"{} + {} = {}".format(num1, num2, num1 + num2) 
Out[7]:
'1 + 3 = 4'
In [8]:
#「{ }」の中に埋め込みたい引数の位置を明示的に番号で与えることもできる
# 引数のタプルのインデックスを指定している
"{0} {1} {2} {1}".format("一個目","二個目","三個目") 
Out[8]:
'一個目 二個目 三個目 二個目'
In [9]:
#リストを展開して文字列に入れたい場合。「*」でリストをばらして引数にできる。
greetings = ["hello", "こんにちは", "ニーハオ"]
"{}, {}, {}".format(*greetings) 
Out[9]:
'hello, こんにちは, ニーハオ'
In [10]:
#floatを入れた場合
"{}".format(1./3) 
Out[10]:
'0.3333333333333333'
In [11]:
#キーワード引数で可読性を上げる
"{arg1} {arg2}".format(arg1=1, arg2=100) 
Out[11]:
'1 100'

注:{ } の数字やキーワードを省略した場合、文字列の中に出てくる { } に0, 1, 2,…と番号をつけていくという処理が行われています。

書式指定子

細かいフォーマットの指定は { } の中に書式指定子を入れることで可能です。

フォーマットの構造 : { [引数の指定] : [書式指定子] }

"{○:△}"の○部分で引数の指定(上記の0,1やarg1など)を行い、△の部分に書式指定子を書きます。○の部分を省略した場合(書式指定子のみを書く場合)、"{:△}"と書きます(コロンは省略できません)。

In [12]:
#小数点以下2桁まで表示
"{:.2f}".format(123.4567)
Out[12]:
'123.46'
In [13]:
#指数表示
"{:.2e}".format(123.4567)
Out[13]:
'1.23e+02'
In [14]:
#指数表示
"{:.3e}".format(123.4567)
Out[14]:
'1.235e+02'
In [15]:
#符号も含め全体で6文字、小数点以下は1桁まで表示
"{:6.1f}".format(-12.34)
Out[15]:
' -12.3'
In [16]:
#符号も含め全体で12文字、小数点以下は2桁まで表示(空白埋め)
"{:12.2e}".format(-12.3456)
Out[16]:
'   -1.23e+01'
In [17]:
#符号を前に出したい場合は、width(幅)の前に"0"をつける
"{:08}".format(-12.34)
Out[17]:
'-0012.34'
In [18]:
#空白埋めの場合はデフォルトにして幅だけ決めれば良い
"{:8}".format(-12.34)  # --> '  -12.34'
Out[18]:
'  -12.34'
In [19]:
#これをベースに小数点以下の桁数などを変更する
"{:06.1f}".format(-12.34)
Out[19]:
'-012.3'
In [20]:
#別の文字で埋めたい場合はこうすると良い
"{:*>8}".format(-12.34)
Out[20]:
'**-12.34'
In [21]:
#整数(空白埋め)
"{:6}".format(-123)
Out[21]:
'  -123'
In [22]:
#整数(ゼロ埋め)
"{:06}".format(-123)
Out[22]:
'-00123'

f-string

Python3.6からf-stringという記法が新しく導入されました。
これは、上述のformat関数を毎回呼ばないといけず、記述がエレガントでない、という理由で生まれました。
通常の文字列の最初に f をつけるだけでf-stringを使うことができます。
使い方はstr.formatとほとんど変わりませんが、 { } の中に変数を埋め込むことができます。

In [23]:
a = 6
f"My favorite number is {a}."
Out[23]:
'My favorite number is 6.'
In [24]:
# 書式指定子もstr.formatと同じものが使用できる
x, y = 3.141592, 3.05
f"{x:.2f} is much larger than {y}."
Out[24]:
'3.14 is much larger than 3.05.'
In [25]:
# {}内はインラインで実行される
f"{1 + 2 + 3}"
Out[25]:
'6'
In [26]:
# リストの要素を以下のように取り出せる
mylist = [6, 4, 10]
f"{mylist[0]} + {mylist[1]} = {mylist[2]}"
Out[26]:
'6 + 4 = 10'

Python3.6で導入されたこのf-stringは非常に便利であり、それだけでもバージョンアップする価値があるかと思います。

(気になる人向け)書式指定子の構造

書式指定子は指定する順番によってどれを指定するかが変わります。
少々分かりにくいですが、公式HPより一般的な書式指定子の書き方を引用してみます。

[ [fill] align] [sign] [#] [0] [width] [.precision] [type]

以下に、指定子をまとめた表を載せます。 利用可能なオプションの詳細は公式HPで確認してください。
おすすめの部分は、数値をフォーマットする場合を前提として書いています。

指定子名 利用可能なオプション 意味 デフォルト おすすめ
fill 任意の文字 空白部分に埋める文字の指定
(alignとセット)
" "(空白部分はスペースで埋める) デフォルト
align "<", ">", "=", "^" 左詰めや右詰めなどの指定 数値なら右詰め、stringなら左詰め 同上
sign "+", "-", " " 符号の表示の仕方 "-"(負数のみ符号を表示) 同上
0 なし、"0" "0"にした場合、符号を前につけ、その間を0埋め なし 0埋めしたい場合はこれのみ指定
# なし, "#" 16進数のとき0xをつけるかどうかなどの指定 ""(デフォルトでなし) デフォルト
width 整数 全体幅の指定(幅より大きい数値ならばそれが収まるような全体幅に自動で変わる 収まるような幅 小さく取ると勝手に大きくなるので、あらかじめ大きめに取っておく
.precision 整数 小数点以下の桁数の指定 16桁くらい 自由にどうぞ
type "b", "d", "e", "E", "f"など 整数や小数の表示方法
(指数表示とか)
小数:固定小数点
整数:10進数
"e", "E"(どちらも指数表示、"E"は1.E01のように大文字になる)もしくは "f"(固定小数点表示)

誤字やおかしい点などがあったら @zawawahoge (Twitter) にお気軽にご連絡ください。

トップページに戻る