获取字典中多个单词的接近匹配

use*_*949 5 python string dictionary fuzzy-search

我有一本具有以下结构的字典:

{
    1: {"names": ["name1_A", "name1_B", ...]},
    2: {"names": ["name2_A", "name2_B", ...]},
    ...
}
Run Code Online (Sandbox Code Playgroud)

其中name1_Aname1_B是写相同的名称,其ID为1的同义词/别名/不同的方式name2_Aname2_B在相同的名称,ID为2的别名,等等。

我需要编写一个接受用户输入并返回其别名与用户输入最相似的名称的ID的函数。

我知道理解我的意思不是很直观,所以这里有个例子。假设这是我的字典:

{
    1: {"names": ["James", "Jamie"]},
    2: {"names": ["Karen", "Karyn"]}
}
Run Code Online (Sandbox Code Playgroud)

用户输入单词Jimmy。由于最接近Jimmy字典的匹配是Jamie,因此该函数必须返回ID 1。

如果用户输入世界Karena,因为最接近的匹配是Karen,该函数必须返回ID 2。

我想获得最接近的数学最好的方法是使用difflibget_close_matches()。但是,该函数将各种可能性作为参数,并且我无法想到在函数中正确使用它的方法。任何帮助,将不胜感激。

cs9*_*s95 7

如果您对第三方模块感兴趣,那么有一个不错的小模块,我喜欢将其用于fuzzywuzzy,用于Python中的模糊字符串匹配。该模块使用Levenshtein距离度量标准来计算两个字符串之间的距离。以下是使用方式的示例:

>>> from fuzzywuzzy import fuzz
>>> from functools import partial
>>> data_dict = {
...     1: {"names": ["James", "Jamie"]},
...     2: {"names": ["Karen", "Karyn"]}
... }
>>> input_str = 'Karena'
>>> f = partial(fuzz.partial_ratio, input_str)
>>> matches = { k : max(data_dict[k]['names'], key=f) for k in data_dict}
>>> matches
{1: 'James', 2: 'Karen'}
>>> { i : (matches[i], f(matches[i])) for i in matches }
{1: ('James', 40), 2: ('Karen', 100)}
Run Code Online (Sandbox Code Playgroud)

现在,您可以提取Karen分数最高的分数。

就本演示而言,我不得不调用该函数两次,但是您应该只能执行一次,这取决于您在本示例中的扩展方式。

要注意的另一件事是,fuzz.partial_ratio它的匹配项更宽松。要使用更严格的匹配方案,请考虑使用fuzz.ratio

您可以在此处使用模糊字符串匹配细读更多示例。