タイトルが示すように、「いいね」という単語のリストがあり、stopWords = ["the", "and", "with", etc...]
「キツネと犬を殺せ」のようなテキストを受け取ります。「Kill fox dog」のような出力が非常に効率的かつ高速に必要です。これを行うにはどうすればよいですか (for ループを使用して反復できることはわかっていますが、あまり効率的ではありません)。
6 に答える
最も重要な改善は、stopWords をset
. これは、ルックアップが非常に高速になることを意味します
stopWords = set(["the", "and", "with", etc...])
" ".join(word for word in msg.split() if word not in stopWords)
ストップワードのいずれかがテキストに含まれているかどうかを知りたいだけの場合
if any(word in stopWords for word in msg.split()):
...
Python では、「ストップワード」をリストではなくセットにして、「x in stopwords」を使用してメンバーシップを直接チェックする操作が最も高速です。この構造は、この種の操作が高速になるように設計されています。
リスト内包表記の使用:
stopWords = ["the", "and", "with"]
msg = "kill the fox and the dog"
' '.join([w for w in msg.split() if w not in stopWords])
与えます:
'kill fox dog'
(他の人が示唆しているように)ストップワードをset()
(他の人が示唆しているように)入れ、他の単語をワーキングセットに蓄積し、...を使用してセットの違いを取得しworking = working - stopWords
、すべてのストップワードがフィルターで除外されたワーキングセットを作成します。または、そのような単語の存在を確認するには、条件付きを使用します。例えば:
#!python
stopWords = set('the a an and'.split())
working = set('this is a test of the one working set dude'.split())
if working == working - stopWords:
print "The working set contains no stop words"
else:
print "Actually, it does"
実際には、より効率的なデータ構造があります。たとえば、大きくて比較的密なストップワードのセットに使用できるトライなどです。Python用のトライモジュールを見つけることができますが、バイナリ(C)拡張として記述されたものは見当たりませんでした。また、純粋なPythonで実装されたトライとPythonのset()
サポートの使用との間のクロスオーバーポイントはどこにあるのでしょうか。(ただし、 Cythonの場合にも適している可能性があります)。
実際、ここで誰かがその質問に個別に取り組んでいることがわかります。SO:cythonでPythonオブジェクトの固定長の可変配列を作成するにはどうすればよいですか。
もちろん、最終的には、単純なセットベースのバージョンを作成し、テストしてプロファイルを作成し、必要に応じて、可能な改善としてtrieおよびCython-trieのバリアントを試してください。
- 元の単語リストを辞書に入れます。
- 単語の区切り文字としてスペースを使用して、指定された文字列内の文字を反復処理します。辞書で各単語を調べます。
別の方法として、リストを正規表現で組み立て、ストップ ワードと周囲のスペースを 1 つのスペースに置き換えることができます。
import re
stopWords = ["the", "and", "with"]
input = "Kill the fox and dog"
pattern = "\\s{:s}\\s".format("\\s|\\s".join(stopWords))
print(pattern)
print(re.sub(pattern, " ", input))
出力します
\sthe\s|\sand\s|\swith\s
Kill fox dog