gpt4 book ai didi

python - Difflib 的 SequenceMatcher - 自定义相等

转载 作者:太空狗 更新时间:2023-10-29 21:58:43 26 4
gpt4 key购买 nike

我一直在尝试使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com