Pythonで5分で便利なことをするレシピ

5分でわかる Python を知らない人が Python の便利さを学べる記事をかいたよ | HIROKI.JPが、Pythonの説明なのにところどころ「Rubyでは」になっていたり、そもそも無理やりPHP的なことをしようとしていていまいちなのでTwitterでひどいなぁと言っていたら

@bellonieta: ここは是非とも@nishioさんに正しい5分記事を書いてもらいたいところ…

と言われてしまった。まー、ぼやくのは生産的じゃないからねぇ。Pythonを使ってて色々便利なことはあるけど、一番手軽そうなものを軽く説明してみよう。たとえばなんか書類をつくっているとするじゃない、こんな感じの。

社長: 山田太郎
支社長: 田中一郎
部長: 山川三郎

面倒なので3人分しか書いてないけど本当はもっとたくさん30行くらいあるとしよう。さー書けた、と思ったらそこに上司が来て「あーあー、そうじゃないよ、『山田太郎(社長)』って書くんだよ」と言うわけですよ。先に言えよ、と。むしろそんな細かいことどっちでもいいじゃん、と。

そこで愚痴りながら30行ちまちまと修正するより、Pythonを使ってサクッと終わらせて「俺スゲー」と悦に入るほうが精神衛生によろしい。さあPythonを立ち上げてみよう。インタプリタが「>>>」と表示して「コードを入れてください」と言うのでu"""と入力してから先程の名前のリストをコピペしよう。u"""は「複数行ユニコード文字列」の開始の印なので、名前のリストを貼り付けたら終了の印"""を付けてからEnterキーを押す。

>>> u"""社長: 山田太郎
... 支社長: 田中一郎
... 部長: 山川三郎
... """
u'\u793e\u9577: \u5c71\u7530\u592a\u90ce\n\u652f\u793e\u9577: \u7530\u4e2d\u4e00\u90ce\n\u90e8\u9577: \u5c71\u5ddd\u4e09\u90ce\n'

ユニコード文字列ができた。これに名前をつけておこう。最後に評価した値は「_」という変数に入っているのでそれにdataって名前をつけよう。

>>> data = _

さて、ここからが面白いところ。まずstripで前後の無駄な空白文字を削り、split("\n")で改行文字区切りのリストに変換する。

>>> data.strip().split("\n")
[u'\u793e\u9577: \u5c71\u7530\u592a\u90ce', u'\u652f\u793e\u9577: \u7530\u4e2d\u4e00\u90ce', u'\u90e8\u9577: \u5c71\u5ddd\u4e09\u90ce']

1行ずつに分割された。分かりやすくするためにここでfor文で表示してみよう。

>>> for line in _: print line
... 
社長: 山田太郎
支社長: 田中一郎
部長: 山川三郎

次にlineをさらに分割してみよう。解説のためにprint line.split()する。

>>> for line in _: print line.split()
... 
[u'\u793e\u9577:', u'\u5c71\u7530\u592a\u90ce']
[u'\u652f\u793e\u9577:', u'\u7530\u4e2d\u4e00\u90ce']
[u'\u90e8\u9577:', u'\u5c71\u5ddd\u4e09\u90ce']

1行ごとに空白の前と後ろに分かれてリストになった。さて次は?文字列フォーマット操作を使おう。

>>> for line in _:
...     items = line.split()
...     print "%s(%s)" % (items[1], items[0])
... 
山田太郎(社長:)
田中一郎(支社長:)
山川三郎(部長:)

おっとコロンが残ってしまった。例えばitems[0].strip(":")でコロンを取り除いてもいいし、items[0][:-1]で最後の1文字だけ捨ててもいい。

>>> for line in _:
...     items = line.split()
...     print u"%s(%s)" % (items[1], items[0][:-1])
... 
山田太郎(社長)
田中一郎(支社長)
山川三郎(部長)

めでたしめでたし。説明のためにまどろっこしく書いたけど、慣れてくると下のようにさくっと書ける。さすがにこれなら5分で出来るだろー。

>>> data = u"""(ここに貼りつけ)"""
>>> for line in data.strip().split("\n"):
...     items = line.split()
...     print u"%s(%s)" % (items[1], items[0][:-1])
... 



追記:

>>> print u"{1}({0})".format(items[0][:-1], items[1])
山川三郎(部長)
>>> print "{1}({0})".format(items[0][:-1], items[1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

これはu"{1}({0})"のuを忘れているのが原因。ユニコード文字列を暗黙のエンコーディングasciiでバイト列に変換するコードになっているが、与えられたデータの中にasciiの範囲じゃないバイトがあるせいでエラーになっている。


他に面白いレシピを思いついた人がいたらトラックバックください!