Disons que j'ai un string
"Hello"
et une liste
words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo','question', 'Hallo', 'format']
Comment trouver les n words
qui sont les plus proches de "Hello"
et présents dans la liste words
?
Dans ce cas, nous aurions ['hello', 'hallo', 'Hallo', 'hi', 'format'...]
La stratégie consiste donc à trier les mots de la liste du mot le plus proche au mot le plus éloigné.
J'ai pensé à quelque chose comme ça
Word = 'Hello'
for i, item in enumerate(words):
if lower(item) > lower(Word):
...
mais c'est très lent dans les grandes listes.
UPDATEdifflib
fonctionne mais il est également très lent. (words list
contient plus de 630000 mots (triés et un par ligne)). La vérification de la liste prend donc 5 à 7 secondes pour chaque recherche du mot le plus proche!
Utilisez difflib.get_close_matches
.
>>> words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']
>>> difflib.get_close_matches('Hello', words)
['hello', 'Hallo', 'hallo']
Veuillez consulter la documentation, car la fonction renvoie par défaut 3 correspondances les plus proches ou moins.
Il existe un article génial avec un code source complet (21 lignes) fourni par Peter Norvig sur la correction orthographique.
http://norvig.com/spell-correct.html
L’idée est de construire toutes les modifications possibles de votre 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)
Maintenant, recherchez chacune de ces modifications dans votre liste.
L'article de Peter est une excellente lecture et mérite d'être lu.
Créez une liste triée de vos mots et utilisez le module bisect - pour identifier le point de la liste triée où votre mot-clé s’adapterait en fonction de l’ordre de tri. En fonction de cette position, vous pouvez donner aux k voisins les plus proches situés au-dessus et au-dessous pour trouver les 2k mots les plus proches.
peut-être que heap peut vous aider.
vous avez un tas nommé Heap
qui jusqu'à ce que sa taille soit inférieure à n
, vous insérez des mots dans Heap
en utilisant la fonction close
[montre que cette chaîne est plus proche qu'une autre chaîne ou non].
cette méthode peut vous aider lorsque n
est petit :)
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)