web-dev-qa-db-ja.com

Pythonのブール値の反対(否定)を取得するにはどうすればよいですか?

次のサンプルの場合:

def fuctionName(int, bool):
    if int in range(...):
        if bool == True:
            return False
        else:
            return True

2番目のif文をスキップする方法はありますか?ブール値boolの反対を返すようにコンピューターに指示するだけですか?

64
amyassin

あなただけを使用することができます:

return not bool
120
jtbandes

not operator (論理否定)

おそらく、最良の方法は演算子notを使用することです。

>>> value = True
>>> not value
False

>>> value = False
>>> not value
True

あなたのコードの代わりに:

if bool == True:
    return False
else:
    return True

次を使用できます:

return not bool

関数としての論理否定

operator モジュール operator.not_ とそのエイリアス operator.__not__ 演算子としてではなく関数として必要な場合:

>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False

これらは、述語関数またはコールバックを必要とする関数を使用する場合に役立ちます。

例えば map または filter

>>> 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つ)を使用したくなるかもしれません。ただし、boolintのサブクラスであるため、「逆ブール」を返さないため、結果は予期しないものになる可能性があり、「逆整数」を返します。

>>> ~True
-2
>>> ~False
-1

なぜなら、True1およびFalseから0と同等であり、ビットごとの反転はintegers1および0

したがって、これらを使用してboolを「ネゲート」することはできません。

NumPy配列(およびサブクラス)による否定

ブール値を含むNumPy配列(またはpandas.Seriespandas.DataFrameなどのサブクラス)を扱っている場合、実際にはビットごとの逆演算子(~)を使用して否定all配列内のブール値:

>>> 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])

NumPy配列でnot演算子またはoperator.not関数を使用することはできません。これらは単一のbool(ブール値の配列ではない)を返す必要があるためですが、NumPyには論理要素ごとに機能する関数ではありません:

>>> 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動作。これを行う場合は、それを明確に文書化し、 (および一般的な)ユースケース。

19
MSeifert

Pythonには「not」演算子がありますよね?それは「ない」だけではありませんか?のように、

  return not bool
9
Patrick87

toggleを実装しようとしているため、永続コードを無効にして再実行するたびに、次のように実現できます。

try:
    toggle = not toggle
except NameError:
    toggle = True

このコードを実行すると、最初にtoggleTrueに設定され、このスニペットが呼び出されるたびに、トグルは無効になります。

2
user1767754