言語処理100本ノックやった 03-06 #python
これのつづきです
たまにチラ見させてもらったりしてます
前回のちょっと改良
#03 円周率
前回の解答
str = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics." str = ''.join([s for s in str if s not in [',', '.']]) list = [len(i) for i in list(str.split(' '))] print list #[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
にしたけど、ピリオドやカンマを取り除くのは .strip() を使うのがいいっぽい。split() で単語ごとにわけたあと strip() の文字列の左右端からかっこの中身を取り除く。ストリップとスプリット語感が似てて困る。
上のは str を list にしてそれを str にして list にしててダサかった
改良版
str = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics." words = str.split() ans = [len(word.strip(',.')) for word in words] print ans
#04 元素記号
前回の回答
str = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can." atom = dict() cnt = 0 for item in str.split(): cnt += 1 if cnt in [1, 5, 6, 7, 8, 9, 15, 16, 19]: atom[item[0]] = cnt else: atom[item[:2]] = cnt print atom
enumerate を使えば自分でカウンターを用意しなくてもいいらしい。
http://docs.python.jp/2/library/functions.html#enumerate
改良版
str = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can." str = str.split() atom = dict() for i, elem in enumerate(str): if i+1 in [1, 5, 6, 7, 8, 9, 15, 16, 19]: atom[elem[0]] = i+1 else: atom[elem[:2]] = i+1 print atom
あんまり変わんないか。
先へ進む
#05 n-gram
与えられたシーケンス(文字列やリストなど)からn-gramを作る関数
最初の解答
from itertools import combinations def ngram(inp, n): ans = [] subs = combinations(xrange(len(inp)), n) for sub in subs: ans.append((inp[sub[0]], inp[sub[1]])) return ans str = "I am an NLPer" print ngram(str.split(), 2) #[('I', 'am'), ('I', 'an'), ('I', 'NLPer'), ('am', 'an'), ('am', 'NLPer'), ('an', 'NLPer')] print ngram([s for s in str if s != ' '], 2)
これを書いたあと、n-gram ってこんなんだっけ?と思って調べる
In the fields of computational linguistics and probability, an n-gram is a *contiguous* sequence of n items from a given sequence of text or speech.
https://en.wikipedia.org/wiki/N-gram
あ、すいませんでした
任意の2組を取るってことではなかった
気を取り直して
def ngram(inp, n): ans = [] for i in xrange(len(inp) -n +1): ans.append(tuple(inp[i:i+n])) return ans str = "I am an NLPer" print ngram(str.split(), 2) # [('I', 'am'), ('am', 'an'), ('an', 'NLPer')] print ngram([s for s in str if s != ' '], 2) # [('I', 'a'), ('a', 'm'), ('m', 'a'), ('a', 'n'), ('n', 'N'), ('N', 'L'), ('L', 'P'), ('P', 'e'), ('e', 'r')]
n個の並びを順番に append しただけ
#06 集合
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合をそれぞれ,XとYとして求め、XとYの和集合、積集合、差集合を求め、さらに,'se'というbi-gramがXおよびYに含まれるかどうかを調べる
def ngram(inp, n): ans = [] for i in xrange(len(inp) -n +1): ans.append(tuple(inp[i:i+n])) return ans #上と同じ prd = "paraparaparadise" prg = "paragraph" prd_2gram = ngram([s for s in prd if s != ' '], 2) prg_2gram = ngram([s for s in prg if s != ' '], 2) X, Y = map(set, [prd_2gram, prg_2gram]) union = X.union(Y) intersection = X.intersection(Y) dif1 = X.difference(Y) dif2 = Y.difference(X) print 'union-> ', union # union-> set([('g', 'r'), ('p', 'h'), ('p', 'a'), ('s', 'e'), ('a', 'p'), ('a', 'g'), ('a', 'd'), ('i', 's'), ('r', 'a'), ('a', 'r'), ('d', 'i')]) print 'intersection-> ', intersection # intersection-> set([('a', 'p'), ('r', 'a'), ('p', 'a'), ('a', 'r')]) print 'X-Y-> ', dif1 # A-B-> set([('a', 'd'), ('s', 'e'), ('d', 'i'), ('i', 's')]) print 'Y-X-> ', dif2 # B-A-> set([('g', 'r'), ('a', 'g'), ('p', 'h')]) print "'se' is in X" if ('s', 'e') in X else "'se' is not in X" # 'se' is in X print "'se' is in Y" if ('s', 'e') in Y else "'se' is not in Y" # 'se' is not in Y
集合はそのまま set()
union intersection difference もそのまま
リストの中身に合わせて ('s', 'e') が入ってるかどうか聞く。そのまま。
X.union(Y) とかの表記、非対称な感じで気持ち悪いなと思ってたら
union = X | Y intersection = X & Y dif1 = X-Y dif2 = Y-X
でよかったらしい。わかりやすすぎる
今日はこんな感じです