ni_haruのブログ

ほぼ日記

Pythonで言語処理100本ノックを解く 05. n-gram

Python言語処理100本ノックを解いてみます。
6本目です。

環境

Ubuntu 16.04.3 LTS
Python 3.5.2

05. n-gram

与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,"I am an NLPer"という文から単語bi-gram,文字bi-gramを得よ.

解答

def _n_gram(target, n):
    return [target[i:i+n] for i in range(0, len(target) - (n -1))]

def word_n_gram(target, n):
    return [" ".join(s) for s in _n_gram(target.split(), n)]

def char_n_gram(target, n):
    return ["".join(s) for s in _n_gram(list(target), n)]

if __name__ == "__main__":
    s = "I am an NLPer"
    print("単語bi-gram",word_n_gram(s, 2))
    print("文字bi-gram",char_n_gram(s, 2))

出力結果

単語bi-gram ['I am', 'am an', 'an NLPer']
文字bi-gram ['I ', ' a', 'am', 'm ', ' a', 'an', 'n ', ' N', 'NL', 'LP', 'Pe', 'er']

冗長かも知れませんが、単語n-gram と文字n-gram で関数を分けました。
両方から呼ばれる関数 n_gram は外部から参照されない関数としたいのですが、pythonにはアクセス制限する修飾子がありません。 (Javaでいうprivateみたいな)
その代わり、先頭に"_"(アンダースコア)を付けることで、「内部でだけ使う」ということを示します。
命名規則なので実際はアクセスできますが、from M import * と書いてもインポートされなくなるので、書くべきでしょう。 (Pythonの慣習等をよく知らないまま書いてます。間違いあれば指摘下さると嬉しいです)

以上です。