heapq push TypeError: '<' не поддерживается между экземплярами - PullRequest
0 голосов
/ 30 ноября 2018

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

TypeError: '<' не поддерживается между экземплярами 'Point' и 'Point' </strong>

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

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

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)

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

0 голосов
/ 30 ноября 2018

Вам необходимо определить относительные операции сравнения в вашем классе 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.

...