Pythonの比較演算子(Pythonでは関係演算子とも呼ばれます)は、2つの被演算子の_値_を調べ、comparisonの条件が満たされるかどうかに応じて、真偽値のTrueまたはFalseを返します。
次の表は、Pythonでよく使われる比較演算子をまとめたものです。
| 演算子 | 演算 | 説明 |
|---|---|---|
> |
「より大きい」 |
aの値がbより厳密に大きいとき、a > bはTrueです |
< |
「より小さい」 |
aの値がbより厳密に小さいとき、a < bはTrueです |
== |
「等しい」 |
aの値がbと厳密に等しいとき、a == bはTrueです |
>= |
「以上」 |
a > bであるか、値がa == bであるとき、a >= bはTrueです |
<= |
「以下」 |
a < bであるか、値がa == bであるとき、a <= bはTrueです |
!= |
「等しくない」 |
a == bがFalseのとき、a != bはTrueです |
is |
「同一性」 |
aとbが同じ_オブジェクト_である場合に限り、a is bはTrueです |
is not |
「同一性の否定」 |
aとbが同じ_オブジェクト_でない場合に限り、a is not bはTrueです |
in |
「包含テスト」 |
aがbのメンバー、部分集合、または要素であるとき、a in bはTrueです |
not in |
「包含テストの否定」 |
aがbのメンバー、部分集合、または要素でないとき、a not in bはTrueです |
これらはすべて同じ優先順位を持ちます(ブール演算より高く、算術演算やビット演算より低い)。
異なる型のオブジェクトは(数値型を除いて)、デフォルトでは決して等しいと判定されません。
classの同一でないインスタンスも、そのclassがデフォルトのobjectの比較の挙動をカスタマイズする特別な拡張比較メソッドを定義していない限り、等しいとは比較され_ません_。
さらに詳しく知りたい場合は、Pythonドキュメントの値の比較を参照してください。
数値型は(ほとんどが)この型一致の規則の例外です。
比較のために暗黙的に変換できるのであれば、integerはfloatと等しいと見なされることもあります(_octalがhexadecimalと等しくなる_場合も同様です)。
その他の数値型(複素数、10進数、分数)では、比較演算子は「意味をなす」ところ(暗黙的な変換が結果を変えないところ)で定義されていますが、比較のために元のオブジェクトを正確に変換できない場合はTypeErrorを送出します。
Pythonが数値変換に用いる規則の詳細については、Pythonドキュメントの算術変換を参照してください。
>>> import fractions
# A string cannot be converted to an int.
>>> 17 == '17'
False
# An int can be converted to float for comparison.
>>> 17 == 17.0
True
# The fraction 6/3 can be converted to the int 2
# The int 2 can be converted to 0b10 in binary.
>>> 6/3 == 0b10
True
# An int can be converted to a complex
# number with a 0 imaginary part.
>>> 17 == complex(17)
True
# The fraction 2/5 can be converted to the float 0.4
>>> 0.4 == 2/5
True
>>> complex(2/5, 1/2) == complex(0.4, 0.5)
True
数値とNaN(非数)型との順序比較は、すべてFalseになります。
PythonのNaNの定義による紛らわしい副作用は、NaNがNaNと決して等しいと比較されないことです。
PythonでなぜNaNがこのように定義されたのかに興味があれば、国際標準の策定をめぐるこちらのNaNに関するStack Overflowの投稿は興味深い読み物です。
>>> x = float('NaN')
>>> 3 < x
False
>>> x < 3
False
# NaN never compares equal to NaN
>>> x == x
False
文字列(str)は、それぞれのUnicodeコードポイント(str内の各コードポイントを組み込み関数ord()に渡した結果で、intを返します)を用いて辞書順に比較されます。
両方の文字列のすべてのコードポイントが一致し、_同じ順序である_場合、2つの文字列は等しいと見なされます。
この比較は「ペアごと」に行われます。つまり、1番目どうし、2番目どうし、というふうに進みます。
Python 3.xでは、strとbytesを直接強制変換したり比較したりすることはできません。
>>> 'Python' > 'Rust'
False
>>> 'Python' > 'JavaScript'
True
# Examples with Mandarin.
# hello < goodbye
>>> '你好' < '再见'
True
# ord() of first characters
>>> ord('你'), ord('再')
(20320, 20877)
# ord() of second characters
>>> ord('好'), ord('见')
(22909, 35265)
# And with Korean words.
# Pretty < beautiful.
>>> '예쁜' < '아름다운'
False
>>> ord('예'), ord('아')
(50696, 50500)
コンテナデータ型(lists、tuples、sets、dictsなど)も辞書順に比較されます。両方のコンテナが同じデータかつ同じデータ型を持つ場合(listsとtuplesの場合は、同じ順序も持つ必要があります)は等しく、それ以外は等しくありません。
>>> [1, 2] == [1, 2]
True
# But if the data is not in the same order, they are not equal.
>>> [2, 1] == [1, 2]
False
# The same holds true for tuples
>>> (3,4,5) == (5,4,3)
False
# Length is also compared
>>> [1, 2] < [1, 2, 3]
True
# Comparing dicts
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 18}
False
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 19}
True
比較演算子は_自由に_連結できます。
式の評価はleftからrightへ向かって行われることに注意してください。
たとえば、x < y <= zはx < y and y <= zと等価ですが、yが一度だけ評価される点が異なります。
どちらの場合も、x < yがFalseであると判明した時点で、zはまったく評価され_ません_。
これはよくshort-circuit evaluationと呼ばれます。式の真偽値がすでに確定していれば、評価はそこで止まります。
Short circuitingは、さまざまなブール演算子や関数でサポートされており、Pythonでは比較の連結でも同様です。
C、C++、C#、Javaを含む多くのほかのプログラミング言語とは異なり、Pythonのa < b < cのような連結式は、従来の数学的な解釈と優先順位を持ちます。
>>> x = 2
>>> y = 5
>>> z = 10
>>> x < y < z
True
>>> x < y > z
False
>>> x > y < z
False
演算子isとis notは、オブジェクトの_値_ではなく、オブジェクトの同一性をテストします。
オブジェクトの同一性は作成後に変わることはなく、id()関数を使って調べられます。
<apple> is <orange>は、id(<apple>) == id(<orange>)である場合に限りTrueと評価されます。
<apple> is not <orange>はその逆を返します。
NoneとNotImplementedはシングルトンであるため、常にisとis notを使って項目と比較するべきです。
この慣習の詳細については、Pythonリファレンスの値の比較とPEP8を参照してください。
# A list of favorite numbers.
>>> my_fav_numbers = [1, 2, 3]
>>> your_fav_numbers = my_fav_numbers
>>> my_fav_numbers is your_fav_numbers
True
# The returned id will differ by system and Python version.
>>> id(my_fav_numbers)
4517478208
# your_fav_numbers is only an alias pointing to the original my_fav_numbers object.
# Assigning a new name does not create a new object.
>>> id(your_fav_numbers)
4517478208
>>> my_fav_numbers is not your_fav_numbers
False
>>> my_fav_numbers is not None
True
>>> my_fav_numbers is NotImplemented
False
演算子inとnot inは_メンバーシップ_をテストします。
<fish> in <soup>は、<fish>が<soup>のメンバーである場合(<fish>が<soup>の部分集合であるか、<soup>に含まれる場合)にTrueと評価され、それ以外はFalseと評価されます。
<fish> not in <soup>は、その否定、つまり<fish> in <soup>の_反対_を返します。
文字列型とbytes型では、<name>が<fullname>の部分文字列である場合に限り、<name> in <fullname>はTrueです。
# A set of lucky numbers.
>>> lucky_numbers = {11, 22, 33}
>>> 22 in lucky_numbers
True
>>> 44 in lucky_numbers
False
# A dictionary of employee information.
>>> employee = {'name': 'John Doe', 'id': 67826, 'age': 33, 'title': 'ceo'}
# Checking for the membership of certain keys.
>>> 'age' in employee
True
>>> 33 in employee
False
>>> 'lastname' not in employee
True
# Checking for substring membership
>>> name = 'Super Batman'
>>> 'Bat' in name
True
>>> 'Batwoman' in name
False
オブジェクトの比較の挙動は、rich comparison methodsを実装することでカスタマイズできます。
詳細については、Pythonチュートリアル: クラス、Pythonのクラスとマジックメソッド(Dan Bader)、特殊メソッド名を参照してください。