2015-12-26 9 views
7

私は以下のようにリストを定義している:Pythonで比較できないオブジェクトのコンパレータの仕組みは?

list = [1,3,2,[4,5,6]] 

その後、以下のようにコンパレータ方式を定義した:

list.sort(reverseCom) 
print list 

Result : [[4, 5, 6], 3, 2, 1]

:今、私はreverseComを使用してリストを並べ替えている

def reverseCom(x,y): 
    if(x>y): 
     return -1 
    elif(x<y): 
     return 1 
    else: 
     return 0 

要素[4,5,6]はリストの他の要素と比較できませんが。どのようにエラーを投げていないのですか?

私は、ソートがPythonでユーザー定義コンパレータとどのように動作するのか理解できますか?

+0

オブジェクトが匹敵するので、エラーは発生しません。つまり、 'list'インスタンスは' int'インスタンスと比較できます。 '[4,5,6]> 3 'を試してください。 'list'は、私が覚えている限り、常に' int'よりも大きくなります。これは比較メソッドが 'list'でどのように定義されるかです。 –

答えて

1

あなたのコンパレータは、実際に動作する、すなわち、任意のエラーをスローしません:

In [9]: reverseCom([4,5,6],1) 
Out[9]: -1 

In [10]: reverseCom([4,5,6],2) 
Out[10]: -1 

In [11]: reverseCom([4,5,6],3) 
Out[11]: -1 

それが動作する理由がある、intインスタンスよりlistインスタンス常に大きな:

In [12]: [1,2,3] > 5 
Out[12]: True 

In [13]: ['hello'] > 5 
Out[13]: True 

In [14]: [] > -1 
Out[14]: True 
+0

@Eliあなたの返事に感謝、私は非常にPythonに新しいです。インスタンス間の比較の仕組みを理解するのを助けてくれますか? 'クラスA:パス'。 'a = A()はa> 10 - > false'を出力します。 A> 10 - > trueを印刷し、 ""> 10000000000000000000 - > true "を出力します。 – Arijit

+0

@Oori私の答えは、Python 2のクレイジーな比較の仕組みに関するより多くの例と情報で更新されました。それを見て、あなたの問題のいくつかを解決するかもしれない。 – zayora

10

これは、Pythonで2奇妙。パイソン2において、数値および非数値は同等であり、数値は常にコンテナオブジェクトの値未満であると考えられる:

>>> 1 < [1] 
True 
>>> 1 < [2] 
True 
>>> 1558 < [1] 
True 
>>> 1 < {} 
True 

一方、異なるタイプの二つの容器値を比較すること

>>>() < [] 
False 
>>> 'tuple' < 'list' 
False 

>>> {} < [] 
True 
>>> 'dict' < 'list' 
True 

この機能は、しかし、もはや同等の数値と非数値を作ったのPython 3で削除されました:考慮されているそのタイプの名前です

編集:この次の説明は、完全に実験ベースであり、私はそれをバックアップするための健全なドキュメントを見つけることができませんでした。誰かがそれを見つけたら、私はそれを読むことがうれしいです。

ユーザ定義のオブジェクト/非コンテナオブジェクトの比較については、Python 2の方がさらに多くのルールがあるようです。

この場合、数値は非数値非コンテナ値よりも常に大きいであるようです。本当に

>>> class A: pass 
... 
>>> class B: pass 
... 
>>> a = A() 
>>> a 
<__main__.A instance at 0x0000000002265348> 
>>> b = B() 
>>> b 
<__main__.B instance at 0x0000000002265048> 
>>> a < b 
False 
>>> b < a 
True 

:異なる、非数値、非コンテナタイプの2つのオブジェクトを比較するとき、今すぐ

>>> class A: pass 
... 
>>> a = A() 
>>> 1 > a 
True 
>>> 2.7 > a 
True 

は、考慮されている彼らのアドレスているようですあなたが私に尋ねるなら、バナナ。あなたは<>事業者の標準的な動作を決定し、あなたのクラス定義の内部__lt__()__gt__()メソッドをオーバーライドするために気にしている場合もちろん

は、すべてのことを周りに変更することができます。

これらのメソッドの動作の詳細については、found hereを参照してください。

ボトムライン:可能な限り異なるタイプの比較を避けてください。結果は実際には予測不可能で、直感的ではなく、そのすべてが十分に文書化されているわけではありません。また、可能な限りPython 3を使用してください。