python - Difflib 的 SequenceMatcher - 自定义相等

标签 python difflib sequencematcher

我一直在尝试使用 SequenceMatcher 创建嵌套或递归效果。

最终目标是比较两个序列,它们都可能包含不同类型的实例。

例如,序列可以是:

l1 = [1, "Foo", "Bar", 3]
l2 = [1, "Fo", "Bak", 2]

通常,SequenceMatcher 只会将 [1] 识别为 l1 和 l2 的公共(public)子序列。

我希望将 SequnceMatcher 应用于字符串实例两次,以便 "Foo""Fo" 将被视为相等, 以及 "Bar""Bak", 最长公共(public)子序列的长度为 3 [1, Foo/Fo, Bar/烘焙]。也就是说,我希望 SequenceMatcher 在比较字符串成员时更加宽容

我尝试做的是为内置 str 类编写一个包装器:

from difflib import SequenceMatcher
class myString:
    def __init__(self, string):
        self.string = string
    def __hash__(self):
        return hash(self.string)
    def __eq__(self, other):
        return SequenceMatcher(a=self.string, b=self.string).ratio() > 0.5

编辑:也许更优雅的方式是:

class myString(str):
    def __eq__(self, other):
        return SequenceMatcher(a=self, b=other).ratio() > 0.5

通过这样做,以下内容成为可能:

>>> Foo = myString("Foo")
>>> Fo = myString("Fo")
>>> Bar = myString("Bar")
>>> Bak = myString("Bak")
>>> l1 = [1, Foo, Bar, 3]
>>> l2 = [1, Fo, Bak, 2]
>>> SequenceMatcher(a=l1, b=l2).ratio()
0.75

所以,显然它在工作,但我对覆盖 hash 函数有一种不好的感觉。 什么时候使用哈希?它哪里会回来咬我?

SequenceMatcher 的文档说明如下:

This is a flexible class for comparing pairs of sequences of any type, so long as the sequence elements are hashable.

根据定义,可哈希元素需要满足以下要求:

Hashable objects which compare equal must have the same hash value.

此外,我是否还需要覆盖 cmp

我很想听听想到的其他解决方案。

谢谢。

最佳答案

您的解决方案还不错 - 您还可以考虑重新设计 SequenceMatcher,以便在序列元素本身是可迭代对象时递归应用一些自定义逻辑。那将是一种痛苦。如果您只需要 SequenceMatcher 的这个功能子集,那么编写自定义 diff 工具也不是一个坏主意。

重写 __hash__ 使 "Foo""Fo" 相等将导致字典(哈希表)等发生冲突。如果您实际上只对前 2 个字符感兴趣并且准备使用 SequenceMatcher,则返回 cls.super(self[2:]) 可能是可行的方法。

综上所述,您最好的选择可能是一次性差异工具。如果你有兴趣,我可以勾勒出类似的基础知识。您只需要知道在这种情况下的约束是什么(子序列是否总是从第一个元素开始,诸如此类)。

关于python - Difflib 的 SequenceMatcher - 自定义相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18672130/

相关文章:

python - 使用 PythonTokenStream 的 PyLucene 自定义 TokenStream

python - 如何使用 win32com 和操作系统迭代修改 Excel 文件类型?

python - 如果我进行一次热编码,我是否总是需要保留一份训练数据的副本?

python - 更改 difflib.make_file() HTML 表的宽度?

python - 表示文本中后续更改并使用 Python 使用此表示的标准方法是什么?

python - 使用 Python 计算并打印子文件夹中的文件数

python - python的difflib.find_longest_match是怎么实现的?

python - 不考虑 difflib.SequenceMatcher isjunk 参数?

python - 使用 fuzzywuzzy 时出现错误 : UserWarning: Using slow pure-python SequenceMatcher. 安装 python-Levenshtein 以删除此警告

python - 方法 set_seq1 和 set_seq2 的工作,difflib python