heapq push TypeError: '<' не поддерживается между экземплярами

Я работаю в Python и у меня есть проблемы с heapq. Когда я помещаю элемент в кучу, я получаю эту ошибку:

Ошибка типа: "<" не поддерживается между экземплярами "Точка" и "Точка"

Точка мой внутренний класс. Я помещаю кортеж, сформированный (float, Point), в соответствии с документацией, heapq должен использовать float в качестве ключа, но это не так. Чтобы быть более точным, иногда используйте float, но не всегда. В чем проблема?

2 ответа

Решение

heapq будет использовать <= оператор на все, что вы положите в него.

Кортежи сравниваются по позиции: первый элемент первого кортежа сравнивается с первым элементом второго кортежа; если они не равны (т. е. первый больше или меньше второго), то это результат сравнения, в противном случае рассматривается второй элемент, затем третий и т. д.

Если первый элемент каждого кортежа уникален, сравнение всегда будет происходить только по первому элементу:

>>> x = (1, object())
>>> y = (2, object())
>>> x <= y
True

(примечание: я использовал object() создать анонимный объект, который не реализует операторы сравнения)

Проблема возникает, когда первый элемент кортежа не является уникальным (т. Е. Первый элемент кортежа будет равен для некоторой пары кортежей), тогда для сравнения придется сравнить второй элемент кортежа:

>>> z = (1, object())
>>> x <= z
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    x <= z
TypeError: '<=' not supported between instances of 'object' and 'object'

Таким образом, либо вы реализуете операторы сравнения в своем объекте, либо убедитесь, что предыдущие элементы в кортеже всегда сопоставимы и вместе являются уникальными.

Например, вы можете добавить идентификатор объекта в кортеж, чтобы ваши кортежи стали:

(priority, id(obj), obj)

так как идентификатор объекта уникален. (будьте осторожны: вы снова столкнетесь с этой проблемой, если добавите два экземпляра одного и того же объекта с одинаковым приоритетом).

Вы должны определить относительные операции сравнения в вашем Point учебный класс. Это означает:

__lt__(self, other) за <

__le__(self,other) за <=

и опционально

__gt__(self, other) за >

__ge__(self, other) за >=,

Последние два являются необязательными, потому что, если не указано, отрицание le а также lt принимаются.

Общая структура этих методов __name__(self, other), где other это объект, который будет сравниваться с self, Также они возвращаются True или же False,

Вы также можете определить __eq__ вместо всех четырех выше, который работает как компаратор в Java. Этот метод должен возвращать положительное целое число, если self больше, чем other, 0, если они равны и отрицательное целое число, если other больше чем self,

Другие вопросы по тегам