Я пытаюсь создать вложенный или рекурсивный эффект с помощью SequenceMatcher.SequenceMatcher Difflib - Индивидуальное равенство
Конечной целью является сравнение двух последовательностей, оба могут содержать экземпляры разных типов.
Например, последовательности могут быть:
l1 = [1, "Foo", "Bar", 3]
l2 = [1, "Fo", "Bak", 2]
Обычно SequenceMatcher будет идентифицировать только [1] в качестве общей подпоследовательности для l1 и l2.
Я хотел бы SequnceMatcher быть применен дважды для струнных экземпляров, так что "Foo"
и "Fo"
будут считаться равными, а также "Bar"
и "Bak"
, а самый длинный общий суб-последовательность будет иметь длину 3 [1, Foo/Fo, Bar/Bak]
. То есть, я бы хотел, чтобы SequenceMatcher был более прощающим при сравнении членов строки.
То, что я пытался делать это написать оболочку для встроенного ул класса:
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
Edit: возможно, более элегантный способ:
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
Таким образом, очевидно, что это работает, но у меня плохое предчувствие перекрывая хэш функция. Когда используется хэш? Где он может вернуться и укусить меня?
документация состоянияSequenceMatcher годов следующие:
Это гибкий класс для сравнения пар последовательностей любого типа, до тех пор, как элементы последовательности являются hashable.
И по определению hashable элементы, необходимые для выполнения следующих требований:
Hashable объекты, которые сравнивают равно должны иметь одинаковое значение хеш-функции.
Кроме того, мне нужно, чтобы переопределить CMP, а?
Мне бы хотелось услышать о других решениях, которые приходят на ум.
Спасибо.
Можете ли вы подробнее рассказать об одноразовом инструменте diff? Разве это не переполнение, чтобы повторно реализовать алгоритм сопоставления? – geckon
Ну, это зависит от ситуации и ограничений. Если вы ищете строгое равенство, кроме как в случае строк (или всех подэлементов?), И порядок всегда один и тот же, и вы знаете, где должно начинаться сопоставление ... Или 2 из этих 3, или что-нибудь еще. Обобщенный алгоритм не всегда лучший, потому что адаптация его к вашим потребностям может быть сложнее, чем просто сделать что-то новое, что делает то, что вы хотите. –
Ну, у меня есть две последовательности (скажем, списки) объектов, и я хочу найти разницу между ними. Но для сравнения я не хочу использовать какой-либо метод класса объектов (даже не '__hash__',' __eq__' и т. Д.), Но я хочу предоставить функцию, которая будет вызываться с каждым объектом в качестве параметра, а возвращаемое значение будет использовано для сравнения. Эта «функция генерации ключей» будет написана мной и может использовать методы класса объектов, стандартные функции и т. Д. И вернется, скажем, строку. Но он может быть более общим (обратный тип). – geckon