pythonで作業していますが、heapqに問題があります。要素をヒープにプッシュすると、次のエラーが発生します。
TypeError: '<'は 'Point'と 'Point'のインスタンス間ではサポートされていません
ポイントは私の内部クラスです。 (float、Point)によって形成されたタプルをプッシュします。ドキュメントによると、heapqはfloatをキーとして使用する必要がありますが、そうではありません。より正確に言うと、floatを使用することもありますが、常にそうとは限りません。何が問題ですか?
heapq
は、入力したものに_<=
_演算子を使用します。
タプルは位置ごとに比較されます。最初のタプルの最初のアイテムが2番目のタプルの最初のアイテムと比較されます。それらが等しくない場合(つまり、最初の項目が2番目の項目よりも大きいか小さい場合)、それは比較の結果です。そうでない場合は、2番目の項目が考慮され、次に3番目の項目が考慮されます。
各タプルの最初のアイテムが一意である場合、比較は常に最初のアイテムでのみ行われます。
_>>> x = (1, object())
>>> y = (2, object())
>>> x <= y
True
_
(注:object()
を使用して、比較演算子を実装しない匿名オブジェクトを作成しました)
この問題は、タプルの最初のアイテムが一意でない場合(つまり、最初のタプルアイテムがタプルのペアごとに等しくなる場合)に発生します。比較では、タプルの2番目のアイテムを比較する必要があります。
_>>> 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'
_
したがって、オブジェクトに比較演算子を実装するか、タプル内の先行する項目が常に比較可能であり、一緒に一意であることを確認します。
たとえば、オブジェクトのIDをタプルに追加して、タプルが次のようになるようにすることができます。
_(priority, id(obj), obj)
_
オブジェクトIDは一意であるため。 (注意:同じ優先度で同じオブジェクトの2つのインスタンスを追加すると、この問題が再び発生します)。
Point
クラスで相対比較演算を定義する必要があります。これの意味は:
__lt__(self, other)
for _<
_
__le__(self,other)
for _<=
_
およびオプションで
__gt__(self, other)
for _>
_
__ge__(self, other)
for _>=
_。
指定しない場合、le
とlt
の否定が行われるため、最後の2つはオプションです。
これらのメソッドの一般的な構造は__name__(self, other)
です。ここで、other
はself
と比較されるオブジェクトです。また、True
またはFalse
を返します。
上記の4つすべての代わりに___eq__
_を定義することもできます。これは、Javaのコンパレータのように機能します。このメソッドは、self
がother
より大きい場合は正の整数を返し、等しい場合は0を返し、other
がself
より大きい場合は負の整数を返します。