8

順序付けが推移的なPython2 の既存の実装はありますか? つまり、ユーザー定義型を作成せずにこの動作を確認することは不可能です。

>>> x < y < z < x
True

この反例のため、CPython は推移的ではありません

x = 'b'
y = ()
z = u'ab'

ただし、CPython でのこの順序付けは、実装の詳細としてのみ 文書化されています。

4

2 に答える 2

2

一部の比較は、Python 2.7では指定されていないと宣言されています。

比較に関する最も重要な一般規則は、 The Python Language Reference の章 5. Expressions / 5.9 Comparisonsにあります。

最初のルールは、数値型 (bool、int、long、float)、文字列 (str、unicode)、タプル、およびリストの比較に関するよく知られたルールです。最後の 2 つの規則は、指定されていないものを宣言します。

  • マッピング (辞書) は、並べ替えられた (キー、値) リストが等しい場合にのみ、等しくなります。[5] 平等以外の結果は一貫して解決されますが、それ以外は定義されません。[6]
  • 組み込み型の他のほとんどのオブジェクトは、同じオブジェクトでない限り、等しくありません。あるオブジェクトを別のオブジェクトよりも小さいと見なすか大きいと見なすかの選択は、任意に行われますが、プログラムの1 回の実行内で一貫して行われます。

多くの特定の規則は、上記の質問で参照されているThe Python Standard Library / Built-in Typesの比較の章、およびcomplexDecimalFractionなどの特定の型に関するドキュメントにあります。

複合型では順序比較はサポートされていないため、TypeError が発生します。Decimal型は値で比較されます。Python 2.7 以降のnumbers.Numberと互換性があります。fractions.Fractionも値で比較されます。


私の考察: 比較の関係が恣意的であり、同じコンピューター上でプログラムを 2 回実行しても再現できない場合、推移性について言及することは役に立ちません。Python 2 で順序が明示的に指定されていない上記のすべてのケースでは、Python 3 で TypeError が発生します。

組み込み型の推移性または順序付けは、異なる組み込み型の値の等価性が実装されている型間でのみ Python 2.7 で壊れていることが知られていますが、それらは他の型と等価に実装されていません。

例: IronPythonの壊れた推移性(Blender のコメントに触発され、簡略化されています):

>>> assert long(0) < 1.0 < [] < long(0)  # 0 < 1; 'float' < 'list' < 'long'

==決定が簡単に見える等価性 ( ) でさえ、常に推移的であるとは限りません。これは、演算子 ( ) の推移性を壊し<=ます。コメントの例を参照してください。(修正ありがとうございます) (同等性は同一性ではありません。 は をa is b意味a == bしますが、その逆はありません。)

例では、1 文字の大文字または小文字の名前を持つ、多くの単純なユーザー定義クラスを使用しています。

class A(object): pass

class a(object): pass
...

class z(object): pass

観察 - 数字

すべての数値型には、CPython と IronPython で自然に同等の値が多数あります (ドキュメントによると、おそらく他のすべての実装でも)。

>>>  assert (False == 0 == 0L == 0.0 == 0 + 0j == Decimal('0') == Fraction(0, 1) <
...          True == 1 == 1L == 1.0 == 1 + 0j == Decimal('1') == Fraction(1, 1))

CPython では、数値型は他のすべての型の前に並べられます。

>>> assert 0 < 10**1000 < float('inf') < A() < Z() < a()

数値型は、IronPython の他の型に分散されています

>>> assert D() < decimal.Decimal('0') < E()
>>> assert F() < fractions.Fraction(0, 1) < G()
>>> assert b() < False < c()   # bool
>>> assert c() < 0 + 0j < d()  # complex
>>> assert f() < 0.0 < g()     # float
>>> assert i() < 0 < j()       # int
>>> assert l() < 0L < m()      # long

ストリングスなど

str、bytearray、および unicode には同等の値があります

>>> assert bytearray('ab') == 'ab' == u'ab'

CPython では、他の型への順序付けに特別なことは使用されません。

>>> assert b() < bytearray('ab') < c()  # bytearray
>>> assert s() < 'ab' < t()             # str
>>> assert u() < u'ab' < v()            # unicode in CPython

IronPython の場合: タイプは のunicodeように動作しstrます。文字列は .NET で Unicode のように実装され、IronPython でも同じであるため、おかしなことではありません。

 >>> assert s() < u'ab' < t()           # unicode in Iron Python like str
 >>> unicode
 <type 'str'>
于 2016-10-22T20:00:41.427 に答える