#
5.9 比較 (comparison)

C 言語と違って、Python における比較演算子は同じ優先順位をもっており、 全ての算術演算子、シフト演算子、ビット単位演算子よりも低くなっています。 また、`a < b < c` が数学で伝統的に用いられているのと同じ解釈に なる点も C 言語と違います:

  `comparison` | ::= | `or_expr ( comp_operator or_expr )*`
  `comp_operator` | ::= | `"<" | ">" | "==" | ">=" | "<=" | "<>" | "!="`
  |  | `| "is" ["not"] | ["not"] "in"`

  Download entire grammar as text.

比較演算の結果はブール値: `True` または `False` になります。

比較はいくらでも連鎖することができます。例えば `x < y <= z` は `x < y and y <= z` と等価になります。ただしこの場合、前者では `y` はただ一度だけ評価される点が異なります (どちらの場合でも、 `x < y` が偽になると `z` の値はまったく評価されません)。

形式的には、 a, b, c, ..., y, z が式で、opa, opb, ..., opy が比較演算子で ある場合、a opa b opb c ...y opy z は a opa b `and` b opb c `and` ... y opy z と等価になります。ただし、前者では各式は多くても一度 しか評価されません。

a opa b opb c と書いた場合、 a から c までの範囲 にあるかどうかのテストを指すのではないことに注意してください。 例えば、`x < y > z` は (きれいな書き方ではありませんが) 完全に正しい文法です。

`<>` と `!=` の二つの形式は等価です; C との整合性を 持たせるためには、`!=` を推奨します; 以下で `!=` について 触れている部分では、`<>` を使うこともできます。 `<>` のような書き方は、現在では古い書き方とみなされています。

演算子 `<`, `>`, `==`, `>=`, `<=`, および `!=` は、二つのオブジェクト間の値を比較します。オブジェクトは 同じ型である必要はありません。双方のオブジェクトが数値であれば、 共通型への変換が行われます。それ以外の場合、異なる型のオブジェクトは 常に 不等であるとみなされ、一貫してはいるが規定されていない 方法で並べられます。

(このような比較演算の変則的な定義は、ソートのような操作や、 `in` および`not in` といった演算子の定義を 単純化するためのものです。将来、異なる型のオブジェクト間における 比較規則は変更されるかもしれません。)

同じ型のオブジェクト間における比較は、型によって異なります:

- 数値間の比較では、算術的な比較が行われます。

- 文字列間の比較では、各文字に対する等価な数値型 (組み込み関数 `ord()` の結果) を使って辞書的な (lexicographically) 比較が行われます。Unicode および 8 ビット文字列は、この動作に関しては 完全に互換です。

- タプルやリスト間の比較では、対応する各要素の比較結果を使って辞書的な 比較が行われます。このため、二つの配列を等価にするためには、各要素が 完全に等価でなくてはならず、配列は同じ型で同じ長さをもっていなければ なりません。

  二つの配列が等価でない場合、異なる値を持つ最初の要素間での比較に 従った順序関係になります。例えば、`cmp([1,2,x], [1,2,y])` は `cmp(x,y)` と等しい結果を返します。片方の要素に対応する要素が 他方にない場合、より短い配列が前に並びます (例えば、 `[1,2] < [1,2,3]` となります)。

- マップ (辞書) 間の比較では、(key, value) からなるリストをソート したものが等しい場合に等価になります。5.3等価性評価以外の結果は一貫したやりかたで解決されるか、定義されないか のいずれかです。5.4

- その他のほとんどの型の比較では、同じオブジェクトでないかぎり 等価にはなりません。あるオブジェクトの他のオブジェクトに対する 大小関係は任意に決定され、一つのプログラムの実行中は一貫した ものとなります。

演算子 `in` および `not in` は、集合内の要素であるか どうか (メンバシップ、membership) を調べます。 `x in s` は、x が集合 s のメンバである 場合には真となり、それ以外の場合には偽となります。 `x not in s` は `x in s` の否定 (negation) を返します。集合メンバシップテストは、伝統的には 配列型に限定されてきました; すなわち、あるオブジェクトがある集合 のメンバとなるのは、集合が配列型であり、配列がオブジェクトと等価な 要素を含む場合でした。しかしながら、現在ではオブジェクトが配列で なくてもメンバシップテストをサポートしています。特に、 辞書型では、`key in dict` と書くことで、 うまい具合にメンバシップテストをサポートしています; 他のマップ型も これに倣っているかもしれません。

リストやタプル型については、`x in y` は `x == y[i]` となるようなインデクス i が存在するとき、かつそのときに限り真になります。

Unicode 文字列または文字列型については、`x in y` は x が y の部分文字列であるとき、かつそのときに限り 真になります。この演算と等価なテストは `y.find(x) != -1` です。 x および y は同じ型である必要はないので注意してください。 すなわち、`u'ab' in 'abc'` は `True` を返すことになります。 空文字列は、他のどんな文字列に対しても常に部分文字列とみなされます。 従って、`"" in "abc"` は `True` を返すことになります。 バージョン2.3 以降で変更された 仕様: 以前は、x は長さ `1` の文字列型でなければ なりませんでした

`__contains__()` メソッドの定義されたユーザ定義クラスでは、 `x in y` が真となるのは `y.__contains__(x)` が真となるとき、かつそのときに限ります。

`__contains__()` は定義していないが `__getitem__()` は定義しているようなユーザ定義クラスでは、 `x in y` は `x == y[i]` となるような非負の整数インデクス i が存在するとき、かつそのときにかぎり真となります。 インデクス i が負である場合に `IndexError` 例外が 送出されることはありません。 (別の何らかの例外が送出された場合、 例外は `in` から送出されたかのようになります)。

演算子 `not in` は、`in` の真値に対する逆転として定義されて います。

演算子 `is` および `is not` は、オブジェクトの アイデンティティに対するテストを行います: `x is y` は、 x と y が同じオブジェクト を指すとき、かつそのときに限り真になります。 `x is not y` は、`is` の真値を逆転したもの になります。

... したものが等しい場合に等価になります。5.3
  実装では、この 演算をリストを構築したりソートしたりすることなく効率的に 行います。
... のいずれかです。5.4
  Python の初期のバージョンでは、ソートされた (key, value) のリストに対して辞書的な比較を行っていましたが、 これは等価性の計算のようなよくある操作を実現するには非常に コストの高い操作でした。もっと以前のバージョンの Python では、辞書は アイデンティティだけで比較されていました。しかしこの仕様は、 `{}` との比較によって辞書が空であるか確かめられると期待して いた人々を混乱させていました。