次のサンプルの場合:
def fuctionName(int, bool):
if int in range(...):
if bool == True:
return False
else:
return True
2番目のifステートメントをスキップする方法はありますか?コンピュータにブール値の反対を返すように指示するだけbool
ですか?
回答:
not
オペレータ(論理否定)おそらく最良の方法は演算子を使用することnot
です:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
だからあなたのコードの代わりに:
if bool == True:
return False
else:
return True
あなたは使うことができます:
return not bool
また、operator
モジュールには2つの関数があり、演算子としてではなく関数として必要な場合operator.not_
のエイリアスoperator.__not__
です。
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
これらは、述語関数またはコールバックを必要とする関数を使用する場合に役立ちます。
>>> lst = [True, False, True, False]
>>> list(map(operator.not_, lst))
[False, True, False, True]
>>> lst = [True, False, True, False]
>>> list(filter(operator.not_, lst))
[False, False]
もちろん、同等のlambda
機能で同じことを実現することもできます。
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
~
ブール値にはビット単位の反転演算子を使用しないでくださいビット単位の反転演算子~
または同等の演算子関数operator.inv
(または、他の3つのエイリアスの1つ)を使用したくなるかもしれません。しかし、結果のbool
サブクラスはint
「逆ブール」を返さないため予期しない可能性があるため、「逆整数」を返します。
>>> ~True
-2
>>> ~False
-1
これTrue
は1
、False
が0
andと同等であり、ビットごとの反転が整数 1
とのビットごとの表現に作用するため0
です。
したがって、これらを使用してを「否定」することはできませんbool
。
あなたがnumpyの配列を扱う(などサブクラスしている場合pandas.Series
やpandas.DataFrame
含むブール値)を、あなたは実際にはビット単位の逆演算子を(使用することができ~
否定する)すべての配列のブール値を:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
または同等のNumPy関数:
>>> np.bitwise_not(arr)
array([False, True, False, True])
not
演算子またはoperator.not
関数をNumPy配列で使用することはできません。これらは単一bool
(ブール値の配列ではない)を返す必要があるためですが、NumPyには要素ごとに機能する論理not関数も含まれています。
>>> np.logical_not(arr)
array([False, True, False, True])
これは非ブール配列にも適用できます。
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
not
bool
値を呼び出して結果を無効にすることで機能します。最も単純なケースでは、真理値は__bool__
オブジェクトを呼び出すだけです。
したがって、実装する__bool__
(または__nonzero__
Python 2で)ことで、真理値をカスタマイズし、その結果をカスタマイズできますnot
。
class Test(object):
def __init__(self, value):
self._value = value
def __bool__(self):
print('__bool__ called on {!r}'.format(self))
return bool(self._value)
__nonzero__ = __bool__ # Python 2 compatibility
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
print
文を追加して、それが本当にメソッドを呼び出していることを確認できるようにします。
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
同様に、__invert__
適用されたときの動作を実装するメソッドを実装できます~
。
class Test(object):
def __init__(self, value):
self._value = value
def __invert__(self):
print('__invert__ called on {!r}'.format(self))
return not self._value
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
もう一度print
呼び出して、それが実際に呼び出されていることを確認します。
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
ただし__invert__
、その動作は「通常の」Pythonの動作とは異なるため、混乱を招く可能性があります。これを行う場合は、それを明確に文書化し、かなり良い(そして一般的な)ユースケースがあることを確認してください。
ここで受け入れられた答えは、所定のシナリオに最も適しています。
ただ、一般的にブール値を単に反転することについては疑問に思いました。ここで認められた解決策は1つのライナーとして機能し、同様に機能する別のワンライナーがあることがわかりました。ブール値であることがわかっている変数「n」があるとすると、それを反転する最も簡単な方法は次のとおりです。
n = n is False
これは私の元の解決策でした、そしてこの質問からの受け入れられた答え:
n = not n
後者はより明確ですが、パフォーマンスについて疑問に思い、それをやり遂げましたtimeit
-そしてn = not n
、ブール値を逆にするためのより速い方法でもあることがわかりました。
トグルを実装しようとしていて、永続コードを無効にして再実行する場合はいつでも、次のように実現できます。
try:
toggle = not toggle
except NameError:
toggle = True
このコードを実行するには、最初に設定されますtoggle
しTrue
、いつでも呼ばれるこのスニペットイストは、トグルは否定されます。
int
、bool
どちらも(それらが表す型の)組み込み名であり、変数名として使用しないでください。