はじめに
SudachiPyのいくつかのメソッドにout
パラメーターが存在します。その引数としてMorphemeList
を渡すと、新しいMorphemeList
を返す代わりに、渡されたMorphemeList
の中身が上書きされます。この挙動はNumPyによく似ています。
対応API
Tokenizer.tokenize()
Morpheme.split()
-
Dictionary.lookup()
(次のバージョン以降のAPI)
使い方
out
パラメーターとしてMorphemeListを渡すと、返り値は同じインスタンスになります。
from sudachipy import Dictionary, SplitMode
tokenizer = Dictionary().create(SplitMode.C)
a_morphemes = tokenizer.tokenize('関西国際空港に行く')
b_morphemes = tokenizer.tokenize('東京に行く', out=a_morphemes)
print(a_morphemes)
print(a_morphemes is b_morphemes)
東京 に 行く
True
Morpheme
はMorphemeList
の中身を参照している
注意しなければいけないのは、Morpheme
は独立のオブジェクトではなく、あくまでMorphemeList
の中を参照しているにすぎません。MorphemeList
を再利用する場合は、Morpheme
の中身も自動的に変わります。
from sudachipy import Dictionary, SplitMode
tokenizer = Dictionary().create(SplitMode.C)
a_morphemes = tokenizer.tokenize('関西国際空港に行く')
m = a_morphemes[0]
print(m)
tokenizer.tokenize('東京に行く', out=a_morphemes)
print(m)
関西国際空港
東京
もし正しくないMorpheme
を参照している場合はエラーになります。
from sudachipy import Dictionary, SplitMode
tokenizer = Dictionary().create(SplitMode.C)
a_morphemes = tokenizer.tokenize('関西国際空港にいった')
m = a_morphemes[-1]
print(m)
b_morphemes = tokenizer.tokenize('東京に行く', out=a_morphemes)
print(m)
た
thread '<unnamed>' panicked at 'index out of bounds: the len is 3 but the index is 3', sudachi.rs\sudachi\src\analysis\mlist.rs:171:25
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
File "scratch_1.py", line 7, in <module>
print(m)
pyo3_runtime.PanicException: index out of bounds: the len is 3 but the index is 3
Morpheme
を不用意に長期間保持しないことをお勧めします。
応用例
すべての分割モードの形態素を羅列する
この機能の応用例として、すべての分割モードで入力を解析する方法を示します。
from sudachipy import Dictionary, SplitMode
tokenizer = Dictionary().create(SplitMode.C)
# MorphemeListの初期化
a_morphemes = tokenizer.tokenize('')
b_morphemes = tokenizer.tokenize('')
text = '美術館と国会議事堂前に行く'
c_morphemes = tokenizer.tokenize(text)
for c_morph in c_morphemes:
print(f'{c_morph=}')
if c_morph.split(SplitMode.B, out=b_morphemes, add_single=False):
for b_morph in b_morphemes:
print(f'\t{b_morph=}')
if b_morph.split(SplitMode.A, out=a_morphemes, add_single=False):
for a_morph in a_morphemes:
print(f'\t\t{a_morph=}')
elif c_morph.split(SplitMode.A, out=a_morphemes, add_single=False):
for a_morph in a_morphemes:
print(f'\t\t{a_morph=}')
c_morph=<Morpheme(美術館, 0:3, (0, 1472589))>
a_morph=<Morpheme(美術, 0:2, (0, 631220))>
a_morph=<Morpheme(館, 2:3, (0, 753593))>
c_morph=<Morpheme(と, 3:4, (0, 102127))>
c_morph=<Morpheme(国会議事堂前, 4:10, (0, 1041988))>
b_morph=<Morpheme(国会, 4:6, (0, 364213))>
b_morph=<Morpheme(議事堂, 6:9, (0, 1523020))>
a_morph=<Morpheme(議事, 6:8, (0, 686995))>
a_morph=<Morpheme(堂, 8:9, (0, 368467))>
b_morph=<Morpheme(前, 9:10, (0, 318429))>
c_morph=<Morpheme(に, 10:11, (0, 113651))>
c_morph=<Morpheme(行く, 11:13, (0, 660689))>
終わりに
この機能は主にユーザの利便性のために開発されました。メモリーの再利用で少しの高速化(数パーセント程度)はできますが、まだ改善の余地があります。
ではよい Sudachi life を。