Pythonの論理演算子の使い方と優先順位[and, or, not]
Pythonのand, or, notなどの基本的な使い方を紹介します。
Pythonでは、論理演算子を使うことで、複数の条件を組み合わせて、1つの真偽値(True
かFalse
)を返すことができます。
以下に、Pythonで使える論理演算子を紹介します。
and(論理積)
and
: 両方の条件が真であればTrue
、それ以外はFalse
を返します。
True and True # True
True and False # False
False and False # False
or(論理和)
or
: 少なくとも1つの条件が真であればTrue
、それ以外はFalse
を返します。
True or True # True
True or False # True
False or False # False
not(否定)
not
: 条件を反転させます。True
をFalse
、False
をTrue
に変換します。
not True # False
not False # True
and, or, notの優先順位
Pythonでは、論理演算子and
、or
、not
について、それぞれ優先順位が定められています。優先順位とは、複数の論理演算子が組み合わさった場合に、どのように評価されるかを決めるものです。
Pythonでは、次のような優先順位が設定されています。
not
and
or
この優先順位を考慮しないと、論理演算子を用いた複雑な論理式が正しく評価されなくなってしまいます。
例えば、次のような論理式を考えます。
not (x > 0) or (y > 0) and (z > 0)
この論理式は、変数x
が0より大きくない、または変数y
が0より大きく、かつ変数z
が0より大きい場合に真を返す論理式です。
この論理式の評価をわかりやすくするために優先度順にカッコでくくると、次のように解釈されます。
(not (x > 0)) or ((y > 0) and (z > 0))
これにより、論理式が正しく評価されるようになります。
以下に、優先順位を考慮した例を示します。
x = 1
y = 2
z = 3
if not (x > 0) or (y > 0) and (z > 0):
print("x は正の値ではない、もしくは、yとzはどちらも正の値である")
else:
print("上記以外")
# "x は正の値ではない、もしくは、yとzはどちらも正の値である"
Pythonのオブジェクトのbool値
Pythonでは、論理演算子and
、or
、not
は、bool型のオブジェクト(True
やFalse
)に対してのみ使用されます。しかし、Pythonでは、bool型以外のオブジェクトに対しても、論理演算子を使用することができます。
Pythonでは、次のような規則に従って、bool型以外のオブジェクトに対して論理演算子が使用されます。
- 数値型のオブジェクト(intやfloatなど): 0は偽、それ以外は真
- 文字列型のオブジェクト: 空文字列は偽、それ以外は真
- シーケンス型のオブジェクト(リストやタプルなど): 空のシーケンスは偽、それ以外は真
- マップ型のオブジェクト(辞書型など): 空のマップは偽、それ以外は真
- ノード型のオブジェクト(ノードを要素とするリンクリストなど): Noneは偽、それ以外は真
- 集合型のオブジェクト(setやfrozensetなど): 空の集合は偽、それ以外は真
例えば、次のように数値型のオブジェクトを論理演算子により評価することができます。
x = 0
if x:
print("x is true")
else:
print("x is false")
# x is false
上の例では、変数x
が0であるため、論理式は偽と評価され、"x is false"という文字列が出力されます。
また、次のように文字列型のオブジェクトを論理演算子により評価することができます。
x = "hello"
if x:
print("x is true")
else:
print("x is false")
# x is true
上の例では、変数x
が空文字列ではないため、論理式は真と評価され、"x is true"という文字列が出力されます。
bool型以外のオブジェクトに対しても、論理演算子を使用することができるため、論理式を記述する際には注意しましょう。
PythonのShort Circuit Evaluation(短絡評価)
Pythonでは、論理演算子のand
やor
において、論理式を評価する際に、"short circuit evaluation"(短絡評価)と呼ばれる手法が用いられます。これは、論理式の左辺を評価したタイミングで式全体の結果が決まっている場合には、それ以降の右辺の指揮を評価せずに結果を返すということです。
例えば、次のような論理式を考えます。
(x > 0) and (y / x > 2)
この論理式は、変数x
が0より大きく、かつ変数y
を変数x
で割った値が2より大きい場合に真を返す論理式です。
もし変数x
が0より小さい場合、変数y
を変数x
で割ることができず、エラーが発生します。これを防ぐために、"short circuit evaluation"が用いられます。この場合、変数x
が0より小さい場合、論理式は偽と評価され、エラーは発生しません。
以下に、具体例を示します。
x = 0
y = 10
if (x > 0) and (y / x > 2):
print("x は正の値で、y / xは2より大きい")
else:
print("x は正の値ではなく、y / xは2以下")
# "x は正の値ではなく、y / xは2以下"
上の例では、変数x
が0であるため、論理式は偽と評価され、"x は正の値ではなく、y / xは2以下"という文字列が出力されます。
or
演算子においても、論理式の左側で結果が既に決定されている場合に、それ以降の論理式を評価せずに結果を返すことができます。例えば、次のような論理式を考えます。
(x == 0) or (y / x > 2)
この論理式は、変数x
が0である、または変数y
を変数x
で割った値が2より大きい場合に真を返す論理式です。
しかし、もし変数y
を変数x
で割ることができず、エラーが発生した場合、論理式の結果もエラーとなります。これを防ぐために、"short circuit evaluation"が用いられます。この場合、変数y
を変数x
で割ることができない場合、論理式は真と評価され、エラーは発生しません。
以下に、具体例を示します。
x = 0
y = 10
if (x == 0) or (y / x > 2):
print("x は0、もしくは、y / xは2より大きい")
else:
print("x は0ではない、かつ、y / xは2以下")
# "x は0、もしくは、y / xは2より大きい"
上の例では、変数x
が0であるため、論理式は真と評価され、"x は0、もしくは、y / xは2より大きい"という文字列が出力されます。
"short circuit evaluation"があることで、論理式を評価する際にエラーが発生することを防ぐことができます。