15

LPTHW を使用していて、理解できないものに遭遇しました。ブール値が必要な場合andor、ブール値以外の値を返す必要があるのはいつですか? LPTHW のテキストには、python などのすべての言語がこの動作をすることが記載されています。彼はインタープリター言語とコンパイル済み言語、またはダック型付き言語と静的型付き言語のどちらを意味するのでしょうか?

次のコードを実行しました。

>>> False and 1
False
>>> True and 1
1
>>> 1 and False
False
>>> 1 and True
True
>>> True and 121
121
>>> False or 1
1
>>> False or 112
112
>>> False or "Khadijah"
'Khadijah'
>>> True and 'Khadijah'
'Khadijah'
>>> False or 'b'
'b'
>>> b = (1, 2, "K")
>>> b
(1, 2, 'K')
>>> False or b
(1, 2, 'K')
>>> 

ここで何が起こっているのかを理解するのを手伝ってください。

ドキュメントによると: http://docs.python.org/2/library/stdtypes.html

ブール値の結果を持つ演算および組み込み関数は、特に明記されていない限り、常にfalse および0orを返します。(重要な例外: ブール演算とは常にオペランドの 1 つを返します。)False1Trueorand

LPTHW によると: http://learnpythonthehardway.org/book/ex28.html True ではなく"test" and "test""test" または1 を返すの はなぜですか? 1 and 1Python や Python に似た多くの言語は、True または False だけでなく、オペランドの 1 つをブール式に返します。つまり、False と 1 を実行すると、最初のオペランド (False) が得られますが、True と 1 を実行すると、2 番目のオペランド (1) が得られます。これで少し遊んでください。

4

4 に答える 4

15

ドキュメントの内容について、あなたはどういうわけか混乱していると思います。次の 2 つのドキュメント セクションをご覧ください: Truth Value Testing と Boolean Operators。最初のセクションの最後の段落を引用するには:

ブール値の結果を持つ演算と組み込み関数は  、特に明記されていない限り、 false と true の場合は常に or を  返し 0 ます 。(重要な例外: ブール演算  と  は常にオペランドの 1 つを返します。)False1Trueorand

ご覧のとおり、操作と組み込み関数については正しいですが、重要な例外の部分を参照してください。ブール演算子がオペランドの 1 つを返すことが十分に述べられています。

現在、それらが返すことができるものは、オペレーターの短絡ロジックにほとんど依存しません。演算子の場合、式orの最初のの値が返されます。これは、1 つが見つかると式全体が真になるためです。すべてのオペランドがfalseyである場合、orは最後のオペランドを返します。つまり、すべてのオペランドを反復処理して、真のオペランドを見つけることができませんでした。

演算子の場合、式が true の場合andは最後のオペランドを返し、式が false の場合は最初の falsey オペランドを返します。ウィキペディアのページ で、短絡評価の詳細を読むことができます。

質問には多くの例があります。それらのいくつかを分析しましょう。

>>> False and 1  # return false (short circuited at first falsey value)
False
>>> True and 1   # return 1 (never short circuited and return the last truthy value)
1
>>> 1 and False  # return false (short circuited at first falsey value, in this case the last operand)
False
>>> 1 and True  # return True (never short circuited and return the last truthy value)
True
>>> True and 121  # return 121 (never short circuited and return the last truthy value)
121
>>> False or 1  # return 1 (since the first operand was falsey, or kept looking for a first truthy value which happened to be the last operator)
1
>>> False or 112  # return 112 for same reason as above
112
>>> False or "Khadijah"  # return "Khadijah" for same reason as above
'Khadijah'
>>> True and 'Khadijah'  # return "Khadijah" because same reason as second example
'Khadijah'

これは一理あると思います。これが役立つ理由をさらに理解するために、次の例を検討してください。

名前をランダムに生成する関数があります

import random

def generate_name():
    return random.choice(['John', 'Carl', 'Tiffany'])

名前が割り当てられているかどうかわからない変数があるので、次のようにします。

if var is None:
    var = generate_name()

ワンライナーを実行できます:

var = var or generate_name()

Noneは偽の値であるためor、検索を続行し、2 番目のオペランドを評価します。これは、最終的に生成された名前を返す関数を呼び出します。これは非常にばかげた例です。この種のスタイルのより良い使用法 (Python ではありませんが) を見てきました。私は今、より良い例を出すことができませんでした。この質問を見ることもできます。トピックに関する非常に役立つ回答があります: Python は短絡をサポートしていますか?

大事なことを言い忘れましたが、これは静的型付け、ダック型付け、動的、インタープリター、コンパイルなど、どの言語とも関係ありません。これは単なる言語機能であり、便利になる可能性があり、私が考えることができるほとんどすべてのプログラミング言語がこの機能を提供しているため、非常に一般的です。

お役に立てれば!

于 2014-03-23T23:43:48.637 に答える
3

次のようなイディオムをサポートするために、 (常にorに評価するのではなく) and をオペランドに評価するand必要があります。orTrueFalse

def foo(self):
    # currentfoo might be None, in which case return the default
    return self.currentfoo or self.defaultfoo()

def foobar(self):
    # foo() might return None, in which case return None
    foo = self.foo()
    return foo and foo.bar()

もちろん、特に慣れていない場合は、そのような慣用句の価値に疑問を抱く可能性があります。明示的な を使用して同等のコードを記述することは常に可能ifです。

それらに対するポイントとして、彼らは、偽の値の全範囲が可能であり、意図的に説明されているのか、それともコメントで言及されているものだけなのか (他の偽の値は許可されていません) に疑問を残しています。Trueしかし、これは一般に、または以外の値である可能性がある値の真性を使用するコードに当てはまりますFalse。誤解を招くことはたまにありますが、めったにありません。

于 2014-03-24T00:07:03.743 に答える
3

これは、Python での短絡効果の実装方法に関係しています。

and(remember ) を使用True and X = Xすると、正しい式の結果がスタックにプッシュされます。false の場合はすぐにポップされ、そうでない場合は 2 番目の式がポップされます。

>>> import dis
>>> 
>>> dis.dis(lambda : True and 0)
  1           0 LOAD_CONST               2 (True)
              3 JUMP_IF_FALSE_OR_POP     9
              6 LOAD_CONST               1 (0)
        >>    9 RETURN_VALUE
>>>
>>> True and 0
0
>>> 0 and True
0
>>>

スマイラーに:

def exec_and(obj1, obj2):
    if bool(obj1) != False:
        return obj2
    return obj1

ではor、最初の式が true の場合、すぐにポップされます。そうでない場合は、2 番目の式がポップされ、結果は 2 番目の式に大きく依存します。

>>> dis.dis(lambda : 0 or False)
  1           0 LOAD_CONST               1 (0)
              3 JUMP_IF_TRUE_OR_POP      9
              6 LOAD_CONST               2 (False)
        >>    9 RETURN_VALUE
>>>
>>> True or 0
True
>>> 1 or False
1
>>> False or 1
1
>>>

スマイラーに:

def exec_or(obj1, obj2):
    if bool(obj1) != True:
        return obj2
    return obj1
于 2014-03-24T00:12:11.017 に答える