【发布时间】:2018-11-24 10:51:57
【问题描述】:
我想使用difflib.get_close_matches 之类的东西,但我想获取索引而不是最相似的字符串(即列表中的位置)。
列表的索引更灵活,因为可以将索引与其他数据结构相关联(与匹配的字符串相关)。
例如,而不是:
>>> words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']
>>> difflib.get_close_matches('Hello', words)
['hello', 'hallo', 'Hallo']
我想要:
>>> difflib.get_close_matches('Hello', words)
[0, 1, 6]
似乎不存在获取此结果的参数,有没有返回索引的difflib.get_close_matches() 的替代方法?
我对替代方案的研究
我知道我可以使用difflib.SequenceMatcher,然后将字符串与ratio(或quick_ratio)进行一对一的比较。但是,我担心这会非常低效,因为:
-
我必须创建数千个 SequenceMatcher 对象并比较它们(我希望
get_close_matches避免使用该类):编辑:错误。我检查了source code of
get_close_matches,它实际上使用了SequenceMatcher。 -
没有截断(我猜有一个优化可以避免计算所有字符串的比率)
编辑:部分错误。代码为
get_close_matches,除了使用real_quick_ratio,quick_ratioandratioalltogether外,没有任何重大优化。无论如何,我可以轻松地将优化复制到我自己的函数中。另外我没有考虑到 SequenceMatcher 有设置序列的方法:set_seq1、set_seq2,所以至少我不必每次都创建一个对象。 -
据我了解,所有 python 库都是 C 编译的,这会提高性能。
编辑:我很确定是这样。该函数位于名为 cpython 的文件夹中。
编辑:直接从 difflib 执行和在文件 mydifflib.py 中复制 the function 之间存在细微差别(p 值为 0.030198)。
ipdb> timeit.repeat("gcm('hello', _vals)", setup="from difflib import get_close_matches as gcm; _vals=['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']", number=100000, repeat=10) [13.230449825001415, 13.126462900007027, 12.965455356999882, 12.955717618009658, 13.066136312991148, 12.935014379996574, 13.082025538009475, 12.943519036009093, 13.149949093989562, 12.970130036002956] ipdb> timeit.repeat("gcm('hello', _vals)", setup="from mydifflib import get_close_matches as gcm; _vals=['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']", number=100000, repeat=10) [13.363269686000422, 13.087718107010005, 13.112324478992377, 13.358293497993145, 13.283965317998081, 13.056695280989516, 13.021098569995956, 13.04310674899898, 13.024205000008806, 13.152750282009947]
尽管如此,它并没有我预期的那么糟糕,我想我会继续,除非有人知道另一个库或替代方案。
【问题讨论】:
标签: python string python-3.x similarity difflib