Pythonひよっこのわたしが、『言語処理100本ノック 2020』の第1章の前半部分に挑戦してみました。
一般の方が公開されている解答と比べながら、1問ずつ学んだことなどをまとめていきたいと思います。
#わたしのこと
大学の授業でC言語(の基礎)を1年半学びました。
Pythonも一部の授業で触れましたが、細かい文法などを学んだのはここ1ヶ月くらいです。
独学で(C言語とちがうところを中心に)基本的な文法を学び、paizaの『レベルアップ問題集』を解いて実装力(?)を高めました。
*詳しいことはブログで書いています: 【Python】paizaのレベルアップ問題集をやってみた!
そんなPythonひよっこが、Pythonの練習もかねて言語処理100本ノックに挑戦してみました!
#第1章:準備運動
##00.文字列の逆順
#00.
text="stressed"
print(text[::-1])
リストのスライスを使います。
3つめの引数(?)stepを -1 にすることで後ろからひとつずつ遡って出力できます。
スライスのこと学んだときは、"スライスに負の数使うときなんてあるの?"って思ってたけど、ありました。
##01.「パタトクカシーー」
#01.
text="パタトクカシーー"
print(text[::2])
構造は00.と同じです。
奇数番目だけ出力すれば良いので、step=2 になります。
##02.「パトカー」+「タクシー」=「パタトクカシーー」
#02.
text1="パトカー"
text2="タクシー"
text3=""
for i in range(len(text1)+len(text2)):
if i%2==0:
text3=text3+text1[i//2]
else:
text3=text3+text2[i//2]
print(text3)
演算子を使って文字列を増やすのに慣れません....
ほかの方の解答を見ると、for文を回す回数をもっと減らすこともできるようです。計算量に関わることなので、回数は少ない方が良いですね。勉強になりました。
##03.円周率
#03.
text="Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
text_new=text.replace('.','').replace(',','')
num_list=[len(x) for x in text_new.split(' ')]
print(num_list)
step1:入力文の , と . を消す
step2:先頭の単語から順番に文字数をカウントする
の順番で実装しました。
step1 は replace() を使って、 ' と . を ''(スペースもなにもないもの)に変換することで , と . を文章中から消します
step2 はfor文の内包表記を利用して、カウントした文字数を num_list に入れていきます。
(内包表記はpaizaのレベルアップ問題集に取り組んだときに身に付けました!)
##04.元素記号
#04.
text="Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
word_list=text.split(' ')
element={}
for i in range(len(word_list)):
if i+1 in [1,5,6,7,8,9,15,16,19]:
word=word_list[i]
element[i]=word[0]
else:
word=word_list[i]
element[i]=word[0:2]
print(element)
パッと浮かんだアルゴリズムでコーディングしましたが、ほかの方の解答をみて、ディクショナリへの追加を一つの関数として定義することでもっと綺麗に書けることがわかりました。
はじめ、 word=~ の処理を忘れてしまったのでちゃんと出力することができませんでした(><)
*問題で求められているようにコーディングしたので、マグネシウムがちがうのはスルーすることにしました。
##05.n-gram
#05.
def n_gram(text,n):
text_len=len(text)
result=[]
for i in range(text_len-n+1):
result.append(text[i:i+n])
return result
text="I am an NLPer"
##単語bi-gram
print(n_gram(text.split(' '),2))
##文字bi-gram
print(n_gram(text,2))
print(n_gram(text.replace(' ',''),2))
単語n-gramが欲しいときは単語ごとに分けた text を、文字n-gramが欲しいときは text そのままを渡せば n-gramが返ってくるような関数n-gram を作成しました。
単語n-gramのときに単語間のスペースを入れて良いのか忘れてしまったのでとりあえず2パターン作りました。
→スペースを認めないn-gramにしたい場合、関数に渡すときにスペースを消去したtextに書き換えます
#おわりに
まだ準備運動、ということもあってどの問題もわりとスラスラと書けたと思います...が、まだ細かいPythonの関数とかに慣れていないので、そのあたりを重点的に練習を続けていきたいと思います!