北海道をこよなく愛するピーターです。
意外にも
「python all and 違い」
「python any or 違い」
で検索してもヒットしなかったので記事に残します。
はじめに
pythonには条件文を書くときに便利な組み込み関数が存在します。
それはall()
とany()
です。
どう便利なのかというと、and
とor
を繰り返し記述しなくて済みます。
記事を書いた背景
これらの便利な関数の使い方についてネットで検索すると、all()
とand
は同一です!という記事ばかりでした。
しかし、両者の挙動は別物です。このことに悩まされたため記事を書きます。
all()とany()を使ってみる(違いがない場合)
実際にand
とor
を使ったコードとall()
とany()
を使ったコードを比較してみます。
a = 1
b = 2
c = 3
#andを使った場合
if a == 1 and b == 2 and c == 3:
print('and int')
#組み込み関数all()を使った場合
if all([a == 1, b == 2, c == 3]):
print('all int')
# and int
# all int
a = 'a'
b = []
c = 1
#orを使った場合
if a == 1 or b == 1 or c == 1:
print('or int')
#組み込み関数any()を使った場合
if any([a == 1, b == 1, c == 1]):
print('any int')
# or int
# any int
このようにall()
やany()
を使うと見た目がスッキリしますね。
挙動が異なるとき
先にコードを記載します。
#型がintであるか判定する関数
def is_int(v):
return type(v) is int
l = [i for i in range(2)]
for i in range(len(l)):
print(f"{i=}")
#orで記述
if is_int(l[i]) or is_int(l[i+1]):
print('or type int')
#anyで記述 i=1のときエラーが発生します
if any([is_int(l[i]), is_int(l[i+1])]):
print('any type int')
print('-'*50)
# i=0
# or type int
# any type int
# --------------------------------------------------
# i=1
# or type int
# IndexError: list index out of range
このように or
のときはエラーが発生しないのにany()
のときはエラーが発生します。
原因
or
ではTrueがあったらそこで条件文の評価を終えて評価を返すのに対し、any()
ではすべての条件文を評価した後に評価を返すことが原因です。
このことをもう少し挙動に迫ったコードで説明します。
検証コード
コード中のhoge
は未定義の変数です。したがって、or
を書くと
NameError: name 'hoge' is not defined
とでるような気がします。どうでしょうか?エラーはでるのでしょうか?
if True or hoge:
print('True')
# True
エラーは出ません!すなわちhoge
は読まれていません。
ではany()
はどうでしょう?
if any([True,hoge]):
print('True')
# NameError: name 'hoge' is not defined
エラーが出ました!listの中身をすべて評価していることが分かります。
まとめ
and
とor
、all()
とany()
は評価方法が違うことが分かりました。
今回の検証ですとand
とall()
は同じ結果になります。ただし、評価方法が違うことは頭に入れておきたいです。いつか役に立つ気がします。
「or
ではうまくいくのにany()
ではうまくいかないのなんでやねん!」と思った方の疑問解決になれば幸いです。