2016-08-27 6 views
0

私はngramsが必要です。私はnltk.utils.ngramsを使ってngramsを得ることができますが、実際にはngrams関数はジェネレータオブジェクトを返します。私はいつもそれを繰り返すことができ、ngramsをリストに格納することができます。しかし、これらのngramを繰り返し実行することなく、リスト内でこれらのngramを取得するための、より直接的な方法がありますか?ジェネレータで反復処理を行う代わりに、NTLKを使用して複数のngramオーダを取得する方法はありますか?

+2

'someList =リスト(someGenerator)を参照してください' - それはうまくいくのだろうか? – georg

+0

nope。空のリストを返す... –

答えて

2

@ georgのコメントはかなり釘付けです。

In [12]: from nltk.util import ngrams 

In [13]: g = ngrams([1,2,3,4,5], 3) 

In [14]: list(g) 
Out[14]: [(1, 2, 3), (2, 3, 4), (3, 4, 5)] 

In [15]: g = ngrams([1,2,3,4,5], 3) 

In [16]: map(lambda x: x, g) 
Out[16]: [(1, 2, 3), (2, 3, 4), (3, 4, 5)] 
+0

確かに!私のPythonインタプリタで何かが起きています...初めて試してみることを拒否しました。今働く。ありがとう! –

+0

短い質問ですが、 'list'でジェネレータをインスタンス化/マテリアライズできるときに' map'を使っているのはなぜですか?効率に違いはありますか? – alvas

+0

@alvas私が知っているわけではありません。私はちょうど異なった方法を見せようとしていた。 –

0

または代わりnltkなし:

from itertools import chain 

def ngrams(L, n = 2): 
    orders = [n] if type(n) is int else sorted(list(n)) 
    return list(chain(*[zip(*[L[i:] for i in range(n)]) for n in orders])) 

>>> ngrams([1,2,3,4,5], n = 3) 
[(1, 2, 3), (2, 3, 4), (3, 4, 5)] 
>>> ngrams([1,2,3,4,5], n = [2,3]) 
[(1, 2), (2, 3), (3, 4), (4, 5), (1, 2, 3), (2, 3, 4), (3, 4, 5)] 
3

実際ngramsの複数の注文を取得するための組み込み関数がありますeverygramsを呼び出し、https://github.com/nltk/nltk/blob/develop/nltk/util.py#L504

>>> from nltk import everygrams 
>>> sent = 'a b c'.split() 
# By default, it will extract every possible order of ngrams. 
>>> list(everygrams(sent)) 
[('a',), ('b',), ('c',), ('a', 'b'), ('b', 'c'), ('a', 'b', 'c')] 
# You can set a max order or ngrams. 
>>> list(everygrams(sent, max_len=2)) 
[('a',), ('b',), ('c',), ('a', 'b'), ('b', 'c')] 
# Or specify a range. 
>>> list(everygrams(sent, min_len=2, max_len=3)) 
[('a', 'b'), ('b', 'c'), ('a', 'b', 'c')] 
関連する問題