我有一个结构如下的字典:
{
1: {"names": ["name1_A", "name1_B", ...]},
2: {"names": ["name2_A", "name2_B", ...]},
...
}
其中name1_A
和name1_B
是同名的同义词/别名/不同写法,其ID为1。name2_A
和name2_B
为同名别名,ID为2,以此类推。
我需要编写一个函数,它接受用户输入并返回其别名与用户输入最相似的名称的 ID。
我知道理解我的意思不是很直观,所以这里有一个例子。假设这是我的字典:
{
1: {"names": ["James", "Jamie"]},
2: {"names": ["Karen", "Karyn"]}
}
用户输入单词 Jimmy
。由于字典中与 Jimmy
最接近的匹配项是 Jamie
,因此该函数必须返回 ID 1。
如果用户在世界 Karena
中键入,因为最接近的匹配项是 Karen
,函数必须返回 ID 2。
我认为获得最接近数学的最好方法是使用 difflib的 get_close_matches()
。但是,该函数将可能性列表作为参数,我想不出在我的函数中正确使用它的方法。任何帮助将不胜感激。
最佳答案
如果您对第 3 方模块感兴趣,我喜欢使用一个名为 fuzzywuzzy
的小模块来处理这类事情。 ,用于 Python 中的模糊字符串匹配。此模块使用 Levenshtein Distance用于计算两个字符串之间距离的度量。这是您如何使用它的示例:
>>> 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)}
现在,您可以提取 Karen
,因为它的得分最高。
为了这个演示的目的,我不得不调用该函数两次,但你应该能够只调用一次,这取决于你如何扩展这个例子。
另一件需要注意的事情是 fuzz.partial_ratio
对其匹配更为宽松。对于更严格的匹配方案,请考虑使用 fuzz.ratio
。
您可以阅读更多使用模糊字符串匹配的示例 here .
关于python - 获取字典中多个单词的接近匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44835047/