False == 0およびTrue == 1は実装の詳細ですか、それとも言語によって保証されていますか?


244

False == 0そしてTrue == 1、Pythonでは(ユーザーによって再割り当てされないと仮定して)が保証されていますか?たとえば、Pythonのバージョン(既存のバージョンと将来のバージョンの両方)に関係なく、次のコードが常に同じ結果を生成することが保証されていますか?

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

公式ドキュメントへの参照は大歓迎です!

編集:多くの回答で述べたように、boolから継承しintます。したがって、質問は次のように書き直すことができます。「ドキュメントでは、プログラマは整数から継承されるブール値に値01?を使用して依存できると公式に言っていますか?」この質問は、実装の詳細が原因で失敗しない堅牢なコードの記述に関連しています。


63
@ S.Lott:上記の質問をする理由はたくさんあります。したがって、ブール値が整数であることに依存することでコードが単純になる場合があります。変更する必要がありますか?または、ブール値が整数であることに依存している他の誰かが書いたコードの場所を見つける可能性があります。既存のコードを「修正」するためにコードで変更していることを中断しますか、または現在のコーディングが適切であると安心できますか?他にも多くの例があります。より一般的には、ゲームのルールを知っておくとよいでしょう。それで、ゲームを上手くプレイして、健全な方法でプログラミングできるようになります。
Eric O Lebigot、

10
@ S.Lott:元の投稿はあなたの主張を正確に反映しています。質問は本質的に「これは実装の詳細ですか?」です。実装の詳細に依存するべきではないという考えに私は完全に同意します。ブール値が公式に既知の値の整数である場合、問題のコードは実装の詳細に依存しないため、これは良いことです。
Eric O Lebigot、

5
@S ロット:False == 0およびTrue == 1であることを知っていると、シーケンス内のブール数がtrueであることが数えやすくなりますsum(bool_list)。そうでなければ、あなたは書く必要がありますsum(1 for x bool_list if x)
dan04

8
@dan:ブール値を数える方法の1つです。それbool_list.count(True)はもっと明白です。また、約3倍高速です... :)
Eric O Lebigot、

2
@akonsu答えが示すように、Pythonのブール値実際には(特定のサブクラスの)整数です。さらに、Pythonに明らかがあります。多分あなたはそれが「静的に型付けされていない」ことを意味しましたか?また、「コードでエラーを起こさない」という意味がわかりません。今、私はブールと整数を混在させるのは好きではありません。それらは概念的に異なるためです。Pythonのブールが整数でなくてもかまいませんが、値が0と1であることがわかっていると便利です。
Eric O Lebigot、2015

回答:


183

Python 2.xでは、再割り当てが可能であり、再割り当てが可能であるため、これは保証されません。ただし、これが発生した場合でも、ブールTrueとブールFalseは比較のために適切に返されます。TrueFalse

Python 3.x TrueおよびFalseはキーワードであり、常におよびと等しく1なり0ます。

Python 2の通常の状況では、常にPython 3です。

Falseオブジェクトのタイプboolは次のサブクラスですint

object
   |
 int
   |
 bool

これが、あなたの例で['zero', 'one'][False]機能する唯一の理由です。リストのインデックス付けは整数、またはメソッドを定義するオブジェクト__index__mark-dickinsonに感謝)でのみ機能するため、整数のサブクラスではないオブジェクトでは機能しません。

編集:

これは、現在のPythonのバージョンの真実である、とPython 3とののpython 2.6のドキュメントPythonの3のためのドキュメントの両方の発言:

整数には2つのタイプがあります:[...] Integers(int)[...] Booleans(bool)

そしてブールサブセクションで:

ブール値:これらは真理値FalseおよびTrue [...]を表します。ブール値は、ほとんどすべてのコンテキストで、それぞれ値0および1のように動作します。例外は、文字列に変換された場合、文字列 "False"または "True "がそれぞれ返されます。

Python 2の場合もあります。

数値コンテキスト(算術演算子の引数として使用される場合など)では、それらは[整数および0]のようにそれぞれ整数0および1のように動作します。

したがって、ブール値はPython 2.6および3では明示的に整数と見なされます。

したがって、Python 4が登場するまでは安全です。;-)


2
0 == 0.0はTrueを返し、['zero'、 'one'] [0.0]は失敗します。['zero'、 'one'] [False]は、boolがintのサブクラスであるため機能します。(int .__ subclasses __()は[<type 'bool'>]を返します)
luc

20
Nitpick:__index__メソッドを提供する任意のオブジェクトをリストインデックスとして使用できます。intまたはのサブクラスだけではありませんlong
Mark Dickinson、

ああ、そうです。しかし、Python 3.0のドキュメントにリンクしない方がよいでしょう。3.0は死んでいます。:)
マークディキンソン

4
再:「Python 2.xでは、TrueとFalseが再割り当てされる可能性があるため、これは保証されません。」私見、これは本当ですが、真または偽を再割り当てする人は誰でも、彼らが得るどんな奇妙な結果にも値するに値します。具体的には、再割り当ての前にTrueを格納し、再割り当て後に結果をTrueと比較すると壊れます。a = True; True = 'i am an idiot'; a == True=>誤り。そのような再割り当てを除いて、デフォルト値は0と1に標準化されており、それに依存することは一般的な慣習だと私は思います。たとえば、[0]が偽の場合、[1]が真の場合、2要素の配列にインデックスを付ける場合。
ToolmakerSteve

Trueは実際には1とFalse 0のように見なすことができるという別の公式の確認に気づきました:docs.python.org/2/library/stdtypes.html#boolean-values。これをこの答えに追加します。
Eric O Lebigot


22

Python 2.xでは、これはまったく保証されていません。

>>> False = 5
>>> 0 == False
False

したがって、それは変わる可能性があります。Python 3.xでは、True、False、Noneは予約語なので、上記のコードは機能しません。

一般に、ブール値では、Falseは常に整数値0(上記のように変更しない限り)ですが、Trueは他の値を持つ可能性があると想定する必要があります。私は必ずしもそのすべての保証に依存するわけではありませんTrue==1が、Python 3.xでは、何があってもこれが常に当てはまります。


3
「Trueは他の値を持つ可能性があります。True== 1であるという保証には必ずしも依存しません。」実際には、あなたが通り、真== 1に頼ることができるpython.org/dev/peps/pep-0285、およびスペックdocs.python.org/2/reference/... 「ブール値は、それぞれ、値が0と1のように振る舞います、ほぼすべての状況で...」Py 2でTrueまたはFalseを再割り当てしてこれをオーバーライドすることは不可能だと言っているわけではありませんが、プロジェクトのプログラマーがばかでそのような再割り当てをしない限り、動作が保証されています。
ToolmakerSteve

-2

とてもシンプル。boolは整数をboolとして評価することに関連しているため、ゼロのみが誤った答えを返します。すべてのゼロ以外の値、浮動小数点数、整数(負の数を含む)、または何を持っているかは、trueを返します。

これが役立つ理由の良い例は、デバイスの電源ステータスの決定です。オンはゼロ以外の値、オフはゼロです。電子的にこれは理にかなっています。

値の間で相対的に真か偽かを判断するには、それと比較する何かが必要です。これは使用して、文字列や数値に適用される==か、!=または<> >=<=、など

変数に整数を割り当て、その変数の値に基づいてtrueまたはfalseを取得できます。


1
問題は、整数のブール値ではなく、True == 1がPythonによって保証されるかどうかです。
エリックOレビゴット2018

-3

ただ、書くint(False)とあなたが得るでしょう0、あなたが入力した場合、int(True)それが出力します1


4
この唯一の手段は、偽と真のに有効な入力であることをint()、彼らは0と1と完全に一致することはない、簡単な数値の意味を持つ、
エリック・O Lebigot

-5

Falseはブール値です。タイプが違います。整数である0とは異なるオブジェクトです。

0 == FalseFalseは整数にキャストされるため、Trueを返します。int(False)は0を返します

==演算子のpythonドキュメントは(help( '=='))と言っています:

演算子<>==>=<=、及び!=二つのオブジェクトの値を比較します。オブジェクトは同じタイプである必要はありません。両方が数値の場合、それらは共通の型に変換されます。

結果として、Falseは比較のために整数に変換されます。ただし、0とは異なります。

>>> 0 is False
False

26
これは正しくありません。 boolはのサブクラスなintので、実際にはブール値整数です。たとえば、isinstance(True, int)Trueを返します。また、等価性チェックではboolがintに変換されません。変換は必要ないため、int.__cmp__直接呼び出すだけです。bool.__cmp__ is int.__cmp__もに評価されることに注意してくださいTrue
Mark Dickinson、

3
この答えは-1です。boolとint(Python 2)の関係についての誤った説明。isinstance(True, int)=>正しい。つまり、真はIS整数、および変換を必要としません。
ToolmakerSteve

私はFalseまたはIntを返すスクリプトがありました...を使用してwhile response is False機能しましたが、機能while response == Falseしませんでした。ありがとう!
curly_brackets

5
それ0 is Falseは誤りであり、何も伝えません。インタラクティブインタープリタでx = -10、then y = -10、thenの順に入力x is yします。これ falseになります。Pythonインタープリターが特定の状況で同じ整数オブジェクトを再利用する最適化が行われているからといって(整数リテラルを定数として格納し、小さな整数をインターンする)is、整数値の等価性をテストするときにこれを使用する必要があるわけではありません。
Martijn Pieters
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.