web-dev-qa-db-ja.com

Python:別の文字列に(リストから)最も近い文字列を見つける

string"Hello"とリストがあるとしましょう

words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo','question', 'Hallo', 'format']

n wordsに最も近く、リストwordsにある"Hello"を見つけるにはどうすればよいですか?

この場合、['hello', 'hallo', 'Hallo', 'hi', 'format'...]になります

したがって、戦略は、リストの単語を最も近い単語から最も遠い単語に並べ替えることです。

私はこのようなことを考えました

Word = 'Hello'
for i, item in enumerate(words):
    if lower(item) > lower(Word):
      ...

しかし、大きなリストでは非常に遅くなります。

[〜#〜] update [〜#〜]difflibは動作しますが、非常に遅いです。 (words listには、630000以上の単語が含まれています(ソートされ、1行に1つ))。そのため、最も近いWordを検索するたびに、リストの確認に5〜7秒かかります。

49
Laura

つかいます - difflib.get_close_matches

>>> words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']
>>> difflib.get_close_matches('Hello', words)
['hello', 'Hallo', 'hallo']

この関数はデフォルトで3以下の最も近い一致を返すため、ドキュメントをご覧ください。

77
Oleh Prypin

スペル修正に関するPeter Norvigから提供された完全なソースコード(21行)を含む素晴らしい記事があります。

http://norvig.com/spell-correct.html

考えは、Wordの可能なすべての編集を構築することです。

hello - helo   - deletes    
hello - helol  - transpose    
hello - hallo  - replaces    
hello - heallo - inserts    


def edits1(Word):
   splits     = [(Word[:i], Word[i:]) for i in range(len(Word) + 1)]
   deletes    = [a + b[1:] for a, b in splits if b]
   transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
   replaces   = [a + c + b[1:] for a, b in splits for c in alphabet if b]
   inserts    = [a + c + b     for a, b in splits for c in alphabet]
   return set(deletes + transposes + replaces + inserts)

次に、リストでこれらの編集のそれぞれを調べます。

ピーターの記事は素晴らしい読み物であり、読む価値があります。

22
Amjith

単語のソート済みリストを作成し、 bisect module を使用して、ソート順に従ってWordが収まるソート済みリスト内のポイントを識別します。その位置に基づいて、2 k個の最も近い単語を見つけるために、上下のk個の最近傍を指定できます。

1
user1308520

多分 heap はあなたを助けることができます。

Heapという名前のヒープがあり、サイズがnより小さくなるまで、関数Heapを使用してcloseに単語を挿入します[この文字列が近いことを示します別の文字列よりも]。

このメソッドは、nが小さいときに役立ちます:)

Heap = []
for Word in words:
    if len(Heap)<n:
       Heap.insert(Word)
    else
       if close(Word,Heap[0]): # it means Heap[0] is the nth farthest Word until now
             Heap.pop():
             Heap.insert(Word)
0
Divuneh