在python difflib库中,SequenceMatcher类是否出现意外行为,或者我误读了所谓的行为是什么?
为什么isjunk参数在这种情况下似乎没有任何区别?
difflib.SequenceMatcher(None, "AA", "A A").ratio() return 0.8
difflib.SequenceMatcher(lambda x: x in ' ', "AA", "A A").ratio() returns 0.8
我的理解是,如果省略空格,则比率应为1.
答案 0 :(得分:0)
这种情况正在发生,因为ratio
函数使用了总序列'计算比率时的长度但不会使用isjunk
过滤元素。因此,只要匹配块中的匹配数导致相同的值(有和没有isjunk
),比率度量就会相同。
我认为由于性能原因,序列不会被isjunk
过滤。
def ratio(self):
"""Return a measure of the sequences' similarity (float in [0,1]).
Where T is the total number of elements in both sequences, and
M is the number of matches, this is 2.0*M / T.
"""
matches = sum(triple[-1] for triple in self.get_matching_blocks())
return _calculate_ratio(matches, len(self.a) + len(self.b))
self.a
和self.b
是传递给SequenceMatcher对象的字符串(序列)(" AA"和" A A"在您的示例中)。 isjunk
函数lambda x: x in ' '
仅用于确定匹配的块。您的示例非常简单,因此两个调用的结果比率和匹配块都相同。
difflib.SequenceMatcher(None, "AA", "A A").get_matching_blocks()
[Match(a=0, b=0, size=1), Match(a=1, b=2, size=1), Match(a=2, b=3, size=0)]
difflib.SequenceMatcher(lambda x: x == ' ', "AA", "A A").get_matching_blocks()
[Match(a=0, b=0, size=1), Match(a=1, b=2, size=1), Match(a=2, b=3, size=0)]
相同的匹配块,比率为:M = 2, T = 6 => ratio = 2.0 * 2 / 6
现在考虑以下示例:
difflib.SequenceMatcher(None, "AA ", "A A").get_matching_blocks()
[Match(a=1, b=0, size=2), Match(a=3, b=3, size=0)]
difflib.SequenceMatcher(lambda x: x == ' ', "AA ", "A A").get_matching_blocks()
[Match(a=0, b=0, size=1), Match(a=1, b=2, size=1), Match(a=3, b=3, size=0)]
现在匹配的块是不同的,但比率将是相同的,因为匹配的数量仍然相等:
当isjunk
为无时:M = 2, T = 6 => ratio = 2.0 * 2 / 6
当isjunk
lambda x: x == ' '
时:M = 1 + 1, T = 6 => ratio = 2.0 * 2 / 6
最后,不同数量的匹配:
difflib.SequenceMatcher(None, "AA ", "A A ").get_matching_blocks()
[Match(a=1, b=0, size=2), Match(a=3, b=4, size=0)]
difflib.SequenceMatcher(lambda x: x == ' ', "AA ", "A A ").get_matching_blocks()
[Match(a=0, b=0, size=1), Match(a=1, b=2, size=2), Match(a=3, b=4, size=0)]
匹配数量不同
当isjunk
为无时:M = 2, T = 7 => ratio = 2.0 * 2 / 7
当isjunk
lambda x: x == ' '
时:M = 1 + 2, T = 6 => ratio = 2.0 * 3 / 7
答案 1 :(得分:0)
您可以在对字符串进行排序之前从字符串中删除字符
def withoutJunk(input, chars):
return input.translate(str.maketrans('', '', chars))
a = withoutJunk('AA', ' ')
b = withoutJunk('A A', ' ')
difflib.SequenceMatcher(None, a, b).ratio()
# -> 1.0