2011-08-22 15 views
45

ユーザ定義クラスをPythonでソート可能またはハッシュ可能にするときに、どのメソッドをオーバーライド/実装する必要がありますか?Pythonユーザ定義クラスをソート可能、ハッシュ可能にする

気を付けることは何ですか?

私はを私の通訳に入力すると、組み込みのdictsのメソッドのリストを取得できます。これらのうち、私はいくつかは、Python2とは対照的に、方法はのpython3のために実装する必要があるに違いがある

['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__'] 

のいくつかのサブセットを実装するために私が必要と仮定しますか?

+3

ここでうまくいっています:http://stackoverflow.com/q/1061283/641766 Python 2.xと3.xの違いは、 '__cmp__'が削除されたことです。 – zeekay

答えて

51

これは他の回答へのコメントとしてほぼ投稿しましたが、それは本当にそれ自体の答えです。

アイテムをソート可能にするには、__lt__を実装する必要があります。これは組み込みの並べ替えで使用される唯一の方法です。

他の比較またはfunctools.total_orderingは、実際にクラスで比較演算子を使用する場合にのみ必要です。

あなたのアイテムをハッシュ可能にするには、他に注意があるように__hash__を実装します。互換性のある方法で__eq__も実装する必要があります。同等のアイテムは、同じものをハッシュする必要があります。

+0

だから '__lt__'の実装が悪いと、pythonが予期せずソートされる可能性がありますか? –

+3

私は「予測不可能」についてはわかりませんが、まったく同じ入力を与えても一貫していますが、入力順序が異なると別の入力が発生する可能性があります(たとえば、x __ lt __(y)とy __ lt __アイテムは異なる順序で表示されます。はい、並べ替えに使用された比較を不適切に実装すると、Pythonは不適切に並べ替えます。インスタンスをタプルに変換する '__key__'関数をお勧めします。次に' __lt__'( '' self____ __() '') ''と__hash__''( '' hash(self .__ key__ ()) ')はそれを使います。 – agf

2

オブジェクトをソート可能にする方法はいくつかあります。

object.__cmp__(self, other) 

そして、あなたはカスタム__hash__関数を定義したい場合は、最後に定義する必要があります。

object.__lt__(self, other) 
object.__le__(self, other) 
object.__eq__(self, other) 
object.__ne__(self, other) 
object.__gt__(self, other) 
object.__ge__(self, other) 

また、唯一の関数を定義することが可能である: - 最初の関数の集合によって定義された豊富な比較、 。 docを参照してください。

+1

Python 3では、「[...] '__cmp __()'特殊メソッドはサポートされなくなりました。[関連セクションはこちら](https://docs.python.org/release/3.0.1/whatsnew /3.0.html#ordering-comparisons)。 –

10

sortability用のPython 2と3

の間に違いはありません。

あなたは比較ですメソッドを定義する必要があります。これはあなたのアイテムをソート可能にします。一般的に、あなたは__cmp__()を好むべきではありません。

私は通常、functools.total_orderingデコレータを使用します。一つ以上の豊富な 比較発注方法を定義するクラスを考えると

functools.total_ordering(CLS)は、このクラスのデコレータは残りを供給します。 これは可能 豊富な比較演算の全てを指定するのに労力を簡素化:

クラスは__lt__()の1、__le__()__gt__()、または __ge__()を定義する必要があります。さらに、クラスは__eq__()メソッドを提供する必要があります。

副作用があるため、比較方法には注意が必要です。あなたは、比較をするときにあなたのクラスを変更したくない。ハッシュに

あなたは__hash__()メソッドを実装する必要があります。私は最良の方法はhash(repr(self))を返すと思うので、あなたのハッシュは一意になります。

+0

ドキュメントの 'functools.total_ordering'の例については、[here](https://docs.python.org/2/library/functools.html#functools.total_ordering)を参照してください。 –

0

__lt__(self,other)を実装する方法は、あなたのクラスをソート可能にする答えです。
組み込みメソッドsorted(iterable)だけでなく、heapqモジュールによる優先キューにも使用できます。

さらに、私はpythonのデザインが好きではないので、多くの'__ge__', '__gt__', '__le__', '__lt__', '__ne__'のメソッドはであり、全く直感的ではありません
対照的に、JavaのInterface Comparable<T>java docを参照)は、このオブジェクトが指定されたオブジェクトよりも小さい、等しい、または大きいので、負の整数、ゼロまたは正の整数を返します。直接でフレンドリー

関連する問題