「言語処理100本ノック 2015」というのを知ったので、ちょっとpythonの勉強のつもりでチャレンジ開始。
まずは「第1章: 準備運動」の00から順に着手。
00. 文字列の逆順
文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.
こんな関数で実現してみました。スライス使うだけですね。
1 2 3 4 5 6 |
def func00(source): """ >>> func00('stressed') 'desserts' """ return source[::-1] |
01. 「パタトクカシーー」
「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.
同じくスライスを使うだけですね。
1 2 3 4 5 6 |
def func01(source): """ >>> func01('パタトクカシーー') 'パトカー' """ return source[::2] |
02. 「パトカー」+「タクシー」=「パタトクカシーー」
「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.
zip関数使って[(‘パ’, ‘タ’),(‘ト’, ‘ク’),…]というタプルのシーケンスを作っておいて、x+yで[‘パタ’, ‘トク’,…]というシーケンスにした上で、joinを使って1つの文字列に…という作りです。
1 2 3 4 5 6 |
def func02(source1, source2): """ >>> func02('パトカー', 'タクシー') 'パタトクカシーー' """ return ''.join([x + y for x, y in zip(source1, source2)]) |
03. 円周率
“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.
いけているかどうかはわかりませんが、これもワンライナーで書いてみました。
1 2 3 4 5 6 |
def func03(source): """ >>> func03('One, two, three.') [3, 3, 5] """ return [len([c for c in x if str.isalpha(c)]) for x in source.split()] |
まずsplitを使って文字列のリストに分割。それぞれの文字列に対してlenで文字列長を取得すれば簡単なのですが、例題には「,」「.」が含まれており、わざわざ「(アルファベットの)」という注記が入っていることから、アルファベットだけのリストに作り直してからlenで要素数を数えるようにしてみました。
ちなみに課題に書かれている”Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文字列を入力すると
1 |
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9] |
というリストが取得できます。
04. 元素記号
“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.
1行がちょっと長くなってきたので、2行に分割。
1 2 3 4 5 6 7 |
def func04(source, pos): """ >>> func04('One Two Three.', [1, 3]) {'O': 1, 'Tw': 2, 'T': 3} """ t = source.split() return {x[:1 if i + 1 in pos else 2]: i + 1 for i, x in list(enumerate(t))} |
enumerateを使ってインデックスを付けることで「何番目」という要求に対応。
1,5,6,…はposで受け取るのですが、インデックスがposで指定された中に含まれていれば1文字、そうでなければ2文字、というのをスライスを使って実現してみました。
ちなみに、課題の”Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”と[1, 5, 6, 7, 8, 9, 15, 16, 19]を引数で渡して実行することで、以下のような辞書を取得できます。
1 |
{'H': 1, 'He': 2, 'Li': 3, 'Be': 4, 'B': 5, 'C': 6, 'N': 7, 'O': 8, 'F': 9, 'Ne': 10, 'Na': 11, 'Mi': 12, 'Al': 13, 'Si': 14, 'P': 15, 'S': 16, 'Cl': 17, 'Ar': 18, 'K': 19, 'Ca': 20} |
まず00〜04までの5題をやってみましたが、どこまで続けられるかな?