有没有替代品`difflib.get_close_匹配项()`返回索引(列表位置)而不是str list?

2024-06-07 20:30:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用类似于^{}但是而不是最相似的字符串,我希望获得索引(即列表中的位置)。在

列表的索引更加灵活,因为可以将索引与其他数据结构(与匹配的字符串相关)相关联。在

例如,代替:

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

我想:

^{pr2}$

似乎不存在一个参数来获得这个结果,有没有一个可以替代difflib.get_close_matches()返回索引的方法?在


我对另一种选择的研究

我知道我可以使用difflib.SequenceMatcher,然后将字符串与ratio(或quick_ratio)进行一对一的比较。但是,我担心这样做会很低效:

  1. 我必须创建数千个SequenceMatcher对象并对它们进行比较(我希望get_close_matches避免使用该类):

    编辑:错误。我检查了source code of ^{},它实际上使用了SequenceMatcher

  2. 没有截止(我猜有一个优化可以避免计算所有字符串的比率)

    编辑:部分错误。代码是get_close_matches没有任何主要的优化,除了使用^{}, ^{} and ^{} alltogether。无论如何,我可以很容易地将优化复制到我自己的函数中。我也没有考虑到SequenceMatcher有设置序列的方法:set_seq1set_seq2,所以至少我不必每次都创建一个对象。

  3. 据我所知,所有python库都是C编译的,这将提高性能。在

    编辑:我很确定是这样。该函数位于名为cpython的文件夹中。在

    编辑:直接从difflib执行与在文件中复制the function之间有一个小差别(p值为0.030198)mydifflib.py. 在

    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]
    

尽管如此,它并不像我预期的那么糟糕,我想除非有人知道另一个图书馆或其他选择,否则我会继续下去。在


Tags: 字符串编辑helloclosegethihouserepeat
1条回答
网友
1楼 · 发布于 2024-06-07 20:30:30

我获取了^{}的源代码,并对其进行了修改,以返回索引而不是字符串值。在

# mydifflib.py
from difflib import SequenceMatcher
from heapq import nlargest as _nlargest

def get_close_matches_indexes(word, possibilities, n=3, cutoff=0.6):
    """Use SequenceMatcher to return a list of the indexes of the best 
    "good enough" matches. word is a sequence for which close matches 
    are desired (typically a string).
    possibilities is a list of sequences against which to match word
    (typically a list of strings).
    Optional arg n (default 3) is the maximum number of close matches to
    return.  n must be > 0.
    Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
    that don't score at least that similar to word are ignored.
    """

    if not n >  0:
        raise ValueError("n must be > 0: %r" % (n,))
    if not 0.0 <= cutoff <= 1.0:
        raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
    result = []
    s = SequenceMatcher()
    s.set_seq2(word)
    for idx, x in enumerate(possibilities):
        s.set_seq1(x)
        if s.real_quick_ratio() >= cutoff and \
           s.quick_ratio() >= cutoff and \
           s.ratio() >= cutoff:
            result.append((s.ratio(), idx))

    # Move the best scorers to head of list
    result = _nlargest(n, result)

    # Strip scores for the best n matches
    return [x for score, x in result]

使用

^{pr2}$

现在,我可以将这些索引与字符串的关联数据关联起来,而不必搜索字符串。在

相关问题 更多 >

    热门问题