7

オブジェクトがPythonで注文可能/ソート可能かどうかを確認するにはどうすればよいですか?

二分木クラスのメソッドの基本的な型チェックを実装しようとして__init__います。ノードの値が順序付け可能かどうかを確認し、そうでない場合はエラーをスローできるようにしたいと考えています。これは、ハッシュテーブルの実装におけるハッシュ可能性のチェックに似ています。

(Ord a) => etc.Haskell の修飾子に似たものを達成しようとしています。Pythonにも同様のチェックがありますか?

4

3 に答える 3

6

オブジェクトがsortableかどうかを知りたい場合は、必要な比較方法が実装されているかどうかを確認する必要があります。

Python 2.Xでは、これらのメソッドを実装する 2 つの異なる方法がありました。

  1. cmp メソッド (例ごとの Java の compareTo に相当)

    __cmp__(self, other): 自分自身が他の値より大きいか、等しいか、または小さいかにかかわらず、>0、0、または <0 を返します。

  2. 豊富な比較方法

    __lt__, __gt__, __eq__, __le__, __ge__, __ne__

    sort() 関数は、このメソッドを呼び出して、インスタンス間で必要な比較を行います (実際には sort には__lt__または__gt__ メソッドのみが必要ですが、それらすべてを実装することをお勧めします)。

Python 3.Xでは__cmp__、同じことを行う方法が複数あることは実際には Python の「法則」に反するため、豊富な比較方法を優先してが削除されました。

したがって、基本的に、これらのメソッドがクラスによって実装されているかどうかを確認する関数が必要です。

# Python 2.X
def is_sortable(obj):
    return hasattr(obj, "__cmp__") or \
           hasattr(obj, "__lt__") or \
           hasattr(obj, "__gt__")

# Python 3.X
def is_sortable(obj):
    cls = obj.__class__
    return cls.__lt__ != object.__lt__ or \
           cls.__gt__ != object.__gt__

Python 2 と 3 では異なる関数が必要です。これは、Python 3 では、バインドされていないメソッド、メソッド ラッパー、およびその他の内部的なものについても多くの変更が加えられているためです。

Python でソート可能なオブジェクトをよりよく理解したい場合は、次のリンクをお読みください。

PS:これは私の最初の回答を完全に再編集したものですが、問題をよりよく調査し、それについてより明確な考えを持っていたので必要でした:)

于 2013-10-28T14:17:52.497 に答える
1

残念ながら、オブジェクトがltを実装していることを確認するだけでは不十分です。numpy は '<' 演算子を使用してブール値の配列を返しますが、これには真偽値はありません。SQL Alchemy はこれを使用してクエリ フィルタを返しますが、これも真理値ではありません。通常のセットはそれを使用してサブセット関係をチェックします。

set1 = {1,2}
set2 = {2,3}
set1 == set2
False
set1 < set2
False
set1 > set2
False

私が考えることができる最良の部分的な解決策 (不明なタイプの単一のオブジェクトから開始) はこれですが、豊富な比較では、順序付け可能性を公式に判断することは不可能のようです:

 if hasattr(x, '__lt__'):
     try:
         isOrderable = ( ((x == x) is True) and ((x > x) is False)
                         and not isinstance(x, (set, frozenset)) )
     except:
         isOrderable = False
 else:
     isOrderable = False
于 2016-03-03T20:32:44.747 に答える