2014/04/01

【Python】文字列フォーマット操作

Pythonで文字列をガシガシ組み上げて行くときに使う

 ←これとか

.format() ←これとか

ひっくるめて「文字列フォーマット操作」について、
最近調べたあたりをメモ。


たとえば
myStr = 'test%stest'
このように、文中に「%s」( モジュロ演算子 + s )と入れておくと、
その部分にあとから別の文字列を入れれるようになります。

こんな感じ。
myStr % 'ABCD'
# result : testABCDtest
%sを含んだ文字列に続けて、 % '(代入したい文字列)'
のように書きます。

複数箇所に代入したい場合は、このように
myStr = 'test%stest%stest'
print myStr % ('ABCD','EFGH')
「%s」を入れたい箇所分いれて、代入する側は()で囲んでおきます。
要はタプル型を渡せば良いわけで(※リストはだめぽいです)、
これでも可
myStr = 'test%stest%stest'
myTpl = ('ABCD','EFGH')
print myStr % myTpl

元の文に仕込んでいる「%s」ですが、
s 以外にもいくつかの組み合わせがあります。s は、文字列を代入したいとき用。
これを「%d」にすると、数値代入用。
myString = 'test%dtest'
print myString % 123

# result : test123test
数値というか、10進整数ですね(decimal のd)。
なので、代入時に小数を与えると切り捨てられます。
myString = 'test%dtest'
print myString % 123.9

# result : test123test

とはいえ、%s を使っていたって数値を文中に代入することは可能です。
%dを使って面白いのは、以下のような使い方。
myString = 'test%04dtest'
print myString % 12

# result : test0012test
このように、% と d の間に「0(桁数)」と書くことで、ゼロパディングができます。

s や d 以外にも組み合わせがあるので、こちらも観てみてください。
http://docs.python.jp/2/library/stdtypes.html#string-formatting


あとは、
タプルではなく辞書型を与えると、キーワードで対応をみて代入してくれます。
myString = 'test%(name)stest%(num)04d'
myDict = {'name':'ABCD','num':456}
print myString % myDict

# result : testABCDtest0456
%と s とか d とかの間に「(〜〜)」と書いておいて、
その〜〜をキーに持つ辞書を与える、という感じになります。


……で、

こうした「モジュロ演算子による文字列フォーマット操作」は、
Python的にやや古いスタイルなようです。
来るべき Python 3系に向けて、
2.6からは下記のようなのが推奨されているとのことです。
http://docs.python.jp/2/library/stdtypes.html#str.format

myStr = 'test{test}test'
print myStr.format(test = 'ABCD')

新しい標準では、% ではなく {〜〜} (「置換フィールド」と呼ぶようです)と、.format()メソッドを使うようです。

さらに、Python 2.7以降だとキーワードを省略できます。
myStr = 'test{}test'
print myStr.format('ABCD')
置換フィールドが空でも、勝手に入ってくれてますね。

代入箇所がたくさんある場合は、こう
myStr = 'this{}is{}test{}'
print myStr.format('ABC','DEF','GHI')

# result : thisABCisDEFtestGHI
順番に入ってくれます。

さらに、代入順を変えるときは
myStr = 'this{1}is{2}test{0}'
print myStr.format('ABC','DEF','GHI')

# result : thisDEFisGHItestABC
{}のなかに数字を入れて順番を指定します。

一番最初の例のようにキーワード指定も可能。.format() への引数として渡します。
旧来式の %(〜〜)s に近い感じですね。
myStr = 'this{stringA}is{stringB}test'
print myStr.format(stringA ='ABC', stringB='DEF')

ほかに、フィールド側で、辞書のキーを指定してしまうことも可能です。
myStr = "this{str[A]}is{str[B]}test"
myDict = {'A':123,'B':456}
print myStr.format(str=myDict)
.format() には「str」しか渡していないのですが、
フィールド側でそれぞれ「str[A]」「str[B]」としているのがミソです。

さらに、オブジェクトを渡してそのアトリビュートを使うことも可能です。
import math
myStr = "this{0.pi}is{0.e}test"
print myStr.format(math)

あとは % のときもあったゼロパディング
'{:0>4}'.format(12)
…ゼロパディングだけの目的ならzfillつかったほうが良さそうですね(^^;
ちなみにこうすると
'{:>4}'.format(12)
ゼロではなくスペースで埋められます。
'{:a>4}'.format(12)
だと a で埋めてくれます。{::>4} だとコロン埋め。
{:>4} で右づめ、{:<4} で左づめ、{:^4}で中央です。
print '{:0>6}'.format(12), '{:a^6}'.format(34),'{::<6}'.format(56)

# result : 000012 aa34aa 56::::


ここにフォーマットの例がありますが、
http://docs.python.jp/2/library/string.html#formatexamples
複雑な例、とかいってすごいなんかやんちゃな奴が書いてあるので、
なんかいろいろ出来そうですね…
ここにリスト内包表記とか使ったらちょっとした宇宙語になりそうですね!
ぜひご一読ください…。

↑このドキュメント読んでて、
この他にも「テンプレート文字列」なんていうのがあるのにも気づきました。
文字列置き換え、奥が深いですね(›´ω`‹ )!!!



■参考

書式指定文字列の文法 @ Python » Documentation » Python 標準ライブラリ »7. 文字列処理
http://docs.python.jp/2/library/string.html#formatstrings

文字列フォーマット操作 @ Python » Documentation » Python 標準ライブラリ »5. 組み込み型
http://docs.python.jp/2/library/stdtypes.html#string-formatting

テンプレート文字列 @ Python » Documentation » Python 標準ライブラリ »7. 文字列処理
http://docs.python.jp/2/library/string.html#id6

ゼロパディングについてすこし @ 萌えるmel読本の中の人が書くブログ
http://sproutmel.blogspot.jp/2013/07/blog-post_25.html

0 件のコメント:

コメントを投稿