any()とall()の紹介
このチュートリアルでは、Python の any()
と all()
関数について説明します。
any(iterable)と
all(iterable)は Python の組み込み関数で、Python 2.5 がリリースされたときから存在しています。
どちらの関数も、渡されたiterableの各要素の間に、それぞれ
orと
and` 演算子を連続して記述することと同じです。
どちらも、定型的なループを置き換えることで、コードを短縮する便利な関数です。
どちらのメソッドも短絡的で、できるだけ早く値を返すので、巨大なイテラブルであっても、可能な限り効率的に処理することができます。
ザ and/or オペレーターズ
これらの関数は and
/or
演算子をベースにしているので、 and
/or
演算子がどのように動作するかを思い出してみましょう。
or 演算子
or演算子は条件 (オペランド) のいずれかが
Trueであれば、
True` と評価されます。
print("(2 == 2) or (3 == 3) evaluates to: " + str((2 == 2) or (3 == 3)))
print("(2 == 2) or (3 == 2) evaluates to: " + str((2 == 2) or (3 == 2)))
print("(2 == 0) or (3 == 2) evaluates to: " + str((2 == 0) or (3 == 2)))
出力
出力: “`
(2 == 2) or (3 == 3) evaluates to: True
(2 == 2) or (3 == 2) evaluates to: True
(2 == 0) or (3 == 2) evaluates to: False
1 つの文の中で複数の `or` を連結することができ、いずれかの条件が `True` であれば、再び `True` と評価されます。
print(str(False or False or False or True or False))
この結果、次のようになります。
True
#### アンド・オペレーター
and` 演算子は、すべての条件が `True` である場合にのみ `True` と評価されます。
print(“(2 == 2) and (3 == 3) evaluates to: ” + str((2 == 2) and (3 == 3)))
print(“(2 == 2) and (3 == 2) evaluates to: ” + str((2 == 2) and (3 == 2)))
print(“(2 == 0) and (3 == 2) evaluates to: ” + str((2 == 0) and (3 == 2)))
出力
出力: ```
(2 == 2) and (3 == 3) evaluates to: True
(2 == 2) and (3 == 2) evaluates to: False
(2 == 0) and (3 == 2) evaluates to: False
orと同様に、複数の
and演算子を連結することができ、すべてのオペランドが
Trueと評価される場合にのみ
True` と評価されます。
print(str(True and True and True and False and True))
この結果は
False
any()
メソッド any(iterable)
は、渡した iterable
の各要素の間で、一連の or
演算子のように振る舞います。
このようなループを置き換えるために使用されます。
for element in some_iterable:
if element:
return True
return False
単純に any(some_iterable)
を呼び出しても同じ結果になります。
print(any([2 == 2, 3 == 2]))
print(any([True, False, False]))
print(any([False, False]))
このコード片を実行すると、次のような結果になります。
True
True
False
Note: any()
を辞書やboolean以外のデータ型で使用した場合、予期しない動作が起こる可能性があります。
もし any()
が辞書で使われた場合、値ではなくキーのどれかが True
と評価されるかどうかがチェックされます。
dict = {True : False, False: False}
print(any(dict))
これは次のように出力されます。
True
一方、 any()
が値をチェックした場合、出力は False
となります。
メソッド any()
は、 map()
メソッドやリスト内包と組み合わせて利用されることが多いです。
old_list = [2, 1, 3, 8, 10, 11, 13]
list_if_even = list(map(lambda x: x % 2 == 0, old_list))
list_if_odd = [x % 2 != 0 for x in old_list]
print(list_if_even)
print(list_if_odd)
print("Are any of the elements even? " + str(any(list_if_even)))
print("Are any of the elements odd? " + str(any(list_if_odd)))
これは出力されます。
[True, False, False, True, True, False, False]
[False, True, True, False, False, True, True]
Are any of the elements even? True
Are any of the elements odd? True
注意: any()
に空の iterable
が渡された場合、このメソッドは False
を返します。
map()、filter()、reduce()関数についてもっと知りたい方は、こちらもどうぞ。
all()
all(iterable)メソッドは、渡した
iterableの各要素の間で、一連の
and` 演算子のように評価されます。
このようなループを置き換えるために使用されます。
for element in iterable:
if not element:
return False
return True
このメソッドは、 iterable
に含まれるすべての要素が True
と評価された場合のみ True
を返し、そうでない場合は False
を返します。
print(all([2 == 2, 3 == 2]))
print(all([2 > 1, 3 != 4]))
print(all([True, False, False]))
print(all([False, False]))
これは出力されます。
False
True
False
False
Note: any()
と同様に、 boolean
以外のデータ型や辞書を渡した場合には、予期せぬ振る舞いが起こる可能性があります。
この場合も、 all()
が辞書と一緒に使用されると、値ではなく、すべてのキーが True
と評価されるかどうかがチェックされます。
もうひとつの any()
との類似点は、 all()
は map()
関数やリスト内包と組み合わせてよく利用されることです。
old_list = ["just", "Some", "text", "As", "An", "example"]
list_begins_upper = list(map(lambda x: x[0].isupper(), old_list))
list_shorter_than_8 = [len(x) < 8 for x in old_list]
print(list_begins_upper)
print(list_shorter_than_8)
print("Do all the strings begin with an uppercase letter? " + str(all(list_begins_upper)))
print("Are all the strings shorter than 8? " + str(all(list_shorter_than_8)))
これは次のように出力されます。
[False, True, False, True, True, False]
[True, True, True, True, True, True]
Do all the strings begin with an uppercase letter? False
Are all strings shorter than 8? True
Note: all()
に空の iterable
が渡された場合、このメソッドは True
を返します! これは、 all()
のコードが iterable
の中に False
の要素があるかどうかをチェックし、空のリストの場合には要素がなく、したがって False
の要素もないためです。
ブーリアン変換とany()関数、all()関数
any 論理演算子を使うとき、つまり any()
や all()
を使うときによくある混乱やエラーの原因は、要素が boolean
データ型でないときに起こるものです。
言い換えると、これらの要素が正確に True
や False
ではなく、 True
や False
に評価されなければならない場合です。
プログラミング言語の中には、ブール値でないデータ型をブール値として評価しないものがあります。
例えば、Javaは if("some string")
や if(15)
といった行を試した場合、使用した型は boolean
に変換できない、と言って文句を言うでしょう。
一方、Pythonはそのようなことはせず、警告を出すことなく、渡されたものを boolean
に変換します。
Pythonはいくつかの例外を除いて、ほとんどのものを True
に変換します。
- 0に等しい数値(0.0を含む)は
False
として扱われます。ここでよくある誤解は、負の値 (-2, -3.3,…) も同様にFalse
として扱われるということです、これらはFalse
としては扱われません! - 空のシーケンス(またはコレクション)は、空の
string
や空のlist
など、すべてFalse
として扱われます。空のiterable
でall()
を使用した場合、予期しない動作が起こる可能性があることに注意してください (True
を返します)。 - 実際の
boolean
値であるFalse
は、特別な値であるNone
と同様に、もちろんFalse
として扱われます。
Python が any()
と all()
を使って他のデータ型を “boolean-ize” する方法をいくつか紹介します。
list_of_strings = ["yet", "another", "example",""]
print("Do all strings have some content?", all(list_of_strings))
list_of_ints = [0, 0.0, -2, -5]
print("Are any of the ints different than 0?", any(list_of_ints))
これは出力されます。
Do all strings have some content? False
Are any of the ints different than 0? True
このような暗黙の boolean
変換を使わないことで、より可読性の高いコードを書くことができることを覚えておいてください。
結論
any()と
all()` の両関数は利便性のために存在し、コードを短くしつつ可読性を維持する場合にのみ使用すべきものです。
この記事では、any()
とall()
関数に飛び込んで、いくつかの例を通してその使い方を紹介しました。