anyとは「1つでも真ならTrue」、allとは「すべて真ならTrue」を返すPythonの組み込み関数です。 どちらもリストなどのイテラブル(for文で1つずつ取り出せるもの)を1つ受け取り、True か False を返します。条件を付けたいときは any(x > 0 for x in nums) のように、かっこの中に内包表記の形で条件を書きます。

この記事では、空リスト・0・空文字・Noneを含む入力ごとの結果を早見表にし、「1つでも含む」「すべて満たす」「1つも満たさない」「ちょうど1つ」といった判定をコピペ用の逆引き表にまとめました。 さらに、ジェネレータ式とリスト内包表記で途中打ち切りが効くかどうかを timeit で計測し、for文とbreakでの書き方との対応、辞書・文字列・NumPy・pandasでの違いまで扱います。コードはすべて Python 3.11.15(NumPy 2.4.4、pandas 3.0.2)で実行し、出力をそのまま載せています。

anyとallの早見表

まずは2つの関数の違いと、よく使う書き方を1枚にまとめます。

項目 any all
意味 1つでも真なら True すべて真なら True
空のイテラブルを渡したとき False True
評価を打ち切るタイミング 最初の真の要素を見つけたとき 最初の偽の要素を見つけたとき
同じ意味の論理演算 a or b or c a and b and c
戻り値 必ず True か False 必ず True か False
引数 イテラブルを1つだけ イテラブルを1つだけ

やりたいことから書き方を探すときは、次の表を使ってください(詳しい逆引き表は後半にあります)。

やりたいこと 書き方
1つでも条件を満たすか any(条件 for x in xs)
すべて条件を満たすか all(条件 for x in xs)
1つも条件を満たさないか not any(条件 for x in xs)
満たさないものが1つでもあるか not all(条件 for x in xs)
ちょうど1つ満たすか sum(条件 for x in xs) == 1
ある値を含むか 値 in xs
空ではなく、かつすべて満たすか bool(xs) and all(条件 for x in xs)

anyとallの基本の使い方

最初に、いちばん基本の形を動かしてみます。ファイルに保存して python3 ファイル名.py で実行できます。

scores = [72, 85, 90, 58]

# any: 1つでも条件を満たせば True
print(any(s >= 90 for s in scores))   # 90点以上が1人でもいるか
# all: すべてが条件を満たせば True
print(all(s >= 60 for s in scores))   # 全員が60点以上か

# 条件を書かずに渡すと、要素そのものの真偽で判定する
print(any([0, "", None]))    # 全部「偽」の値
print(all([1, "a", [0]]))    # 全部「真」の値

実行結果(Python 3.11.15):

True
False
False
True

ポイントは2つです。

  • 条件を付けるときは、かっこの中に「条件 for 変数 in リスト」と書く(これをジェネレータ式と呼びます。リスト内包表記から角かっこを取った形です)。
  • 条件を書かずにリストをそのまま渡すと、要素そのものが真か偽かで判定する。Python では 0、0.0、空文字、None、空のリスト・辞書・タプルなどが「偽」として扱われ、それ以外は「真」として扱われます。

Python の公式ドキュメント(組み込み関数のページ)では、all は「iterable の全ての要素が真ならば(もしくは iterable が空ならば)True を返す」、any は「iterable のいずれかの要素が真ならば True を返し、空なら False を返す」と説明されています。今回このページを開いて確かめました。

入力ごとの結果がわかる真理値の早見表

「0 が入っていたらどうなるのか」「None だけのリストはどうか」といった疑問に、実行結果で答えます。次のスクリプトで16通りの入力を一度に確かめました。

cases = [
    [], [True, True], [True, False], [False, False],
    [0], [0, 1], [1, 2, 3], [0.0],
    [""], ["", "a"], ["a", "b"], ["0"],
    [None], [None, 1], [[]], [[], [0]],
]
print(f"{'入力':<16}{'any':<7}{'all'}")
for c in cases:
    print(f"{c!r:<18}{any(c)!s:<7}{all(c)}")

実行結果:

入力              any    all
[]                False  True
[True, True]      True   True
[True, False]     True   False
[False, False]    False  False
[0]               False  False
[0, 1]            True   False
[1, 2, 3]         True   True
[0.0]             False  False
['']              False  False
['', 'a']         True   False
['a', 'b']        True   True
['0']             True   True
[None]            False  False
[None, 1]         True   False
[[]]              False  False
[[], [0]]         True   False

同じ結果を、理由つきの表にまとめます。

入力 any all 読み方
[] False True 空。anyは「真が1つもない」、allは「偽が1つもない」
[True, True] True True すべて真
[True, False] True False 真と偽が混ざる
[False, False] False False すべて偽
[0] False False 数値の0は偽
[0, 1] True False 1が真、0が偽
[1, 2, 3] True True 0以外の数値は真
[0.0] False False 小数の0.0も偽
[""] False False 空文字は偽
["", "a"] True False 空でない文字列は真
["0"] True True 文字列の"0"は空ではないので真
[None] False False Noneは偽
[None, 1] True False Noneと真の値が混ざる
[[]] False False 中身が空リスト1つ。空リストは偽
[[], [0]] True False [0] は空ではないので真

覚え方は「anyは真を探す、allは偽を探す」です。 any は真が1つ見つかれば True、最後まで見つからなければ False。all は偽が1つ見つかれば False、最後まで見つからなければ True になります。

つまずきやすいのは次の3点です。

  • 文字列の "0" や "False" は真です。フォームやCSVから読み込んだ値は文字列なので、数値として判定したいときは int(x) != 0 のように変換してから条件を書きます。
  • [[]] は「空リストが1つ入ったリスト」で、空ではありません。中の要素(空リスト)が偽なので、any も all も False になります。
  • 0 を「有効な値」として扱いたいときは、要素そのものの真偽ではなく all(x is not None for x in xs) のように条件を明示します。

all([])がTrueになる理由

all([]) が True になるのは、仕様としてそう決められているからで、理由は3つの見方で説明できます。

1. 「偽の要素が1つもない」から

all は「偽の要素を探して、見つかったら False を返す」関数です。空のリストには要素がないので、偽の要素も見つかりません。したがって True が返ります。公式ドキュメントに載っている同等のコードを見ると、この動きがそのまま読み取れます。

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True      # 一度もループに入らなければ、ここに来る

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False     # 一度もループに入らなければ、ここに来る

2. リストを分割しても結果が変わらないようにするため

all(a + b) は all(a) and all(b) と同じ結果になるのが自然です。ここで b が空リストだった場合、all(a) and all([]) が all(a) と一致するには、all([]) が True である必要があります。同じ考え方で、any(a + b) が any(a) or any(b) と一致するには、any([]) は False である必要があります。足し算で「何も足さない」が 0、掛け算で「何も掛けない」が 1 になるのと同じ関係です。

3. 日常の言葉でも成り立つから

「この箱に入っているペンはすべて赤い」という文は、箱が空のときに反例(赤くないペン)を1本も示せません。論理学ではこれを「空虚な真」と呼び、真として扱います。

とはいえ、「空のときは False にしたい」場面はよくあります。 たとえば「入力された項目がすべて有効か」を調べるとき、項目が0件なら通したくない、という場合です。そのときは空でないことを一緒に確かめます。

items = []

# 空でも True になる
print(all(x > 0 for x in items))                  # True

# 空のときは False にしたい
print(bool(items) and all(x > 0 for x in items))  # False

リストやタプルなら bool(items) や len(items) > 0 で空かどうかがわかります。

for文とbreakで書いた場合との対応

any と all は、for文と break で書いていた処理を1行にまとめたものです。対応を並べて確かめます。

nums = [4, 8, 15, 16]

# any と同じ意味の for 文
found = False
for n in nums:
    if n > 10:
        found = True
        break
print(found, any(n > 10 for n in nums))

# all と同じ意味の for 文
ok = True
for n in nums:
    if not n > 0:
        ok = False
        break
print(ok, all(n > 0 for n in nums))

# for-else:break しなかったときだけ else が動く
for n in nums:
    if n < 0:
        print("負の数があります")
        break
else:
    print("負の数はありません")

実行結果:

True True
True True
負の数はありません
for文での書き方 any / all での書き方
フラグを False で用意し、条件を満たしたら True にして break any(条件 for x in xs)
フラグを True で用意し、条件を満たさなければ False にして break all(条件 for x in xs)
for-else(break しなかったら else) if not any(条件 for x in xs):
関数の中で、見つけたら return True、最後に return False return any(条件 for x in xs)

どちらを選ぶかの目安は「True か False だけがほしいかどうか」です。 判定結果だけがほしいなら any / all が短く書けます。見つけた要素を使って別の処理をしたい、途中でログを出したい、といった場合は for文のほうが読みやすくなります。

途中打ち切りはジェネレータ式で効く

any は真が見つかった時点で、all は偽が見つかった時点で、残りの要素を見ずに結果を返します(短絡評価と呼びます)。ただし、かっこの中をジェネレータ式で書くか、リスト内包表記で書くかで、条件の計算回数が変わります。 条件の関数に print を入れて確かめます。

def check(n):
    print("  check", n)
    return n >= 3

nums = [1, 3, 5, 7]

print("any + ジェネレータ式")
print(any(check(n) for n in nums))

print("any + リスト内包表記")
print(any([check(n) for n in nums]))

print("all + ジェネレータ式")
print(all(check(n) for n in nums))

実行結果:

any + ジェネレータ式
  check 1
  check 3
True
any + リスト内包表記
  check 1
  check 3
  check 5
  check 7
True
all + ジェネレータ式
  check 1
False
  • ジェネレータ式(any(check(n) for n in nums))は、3 で条件が真になった時点で止まり、5 と 7 は調べていません。
  • リスト内包表記(any([check(n) for n in nums]))は、まず角かっこの中で4つすべてを計算してリストを作り、そのあとで any が先頭から見ていきます。any 自体は2つ目で止まりますが、条件の計算はすでに全件終わっています。
  • all も同じで、最初の 1 が条件を満たさないとわかった時点で止まっています。

timeitで計測した結果

100万件のリストから値を探す処理で、書き方ごとの時間を計測しました。

import sys
import timeit

N = 1_000_000
data = list(range(N))

def loop(target):
    for x in data:
        if x == target:
            return True
    return False

def ms(func):
    # 5回実行を3セット行い、最も速いセットの1回あたりをミリ秒で返す
    return min(timeit.repeat(func, number=5, repeat=3)) / 5 * 1000

print("Python", sys.version.split()[0], "/ 要素数", N)
for label, t in [("先頭で見つかる", 0), ("中央で見つかる", N // 2), ("見つからない", -1)]:
    print(label)
    print(f"  any(ジェネレータ式)   {ms(lambda: any(x == t for x in data)):9.4f} ms")
    print(f"  any([リスト内包表記]) {ms(lambda: any([x == t for x in data])):9.4f} ms")
    print(f"  for文 + return        {ms(lambda: loop(t)):9.4f} ms")
    print(f"  in 演算子             {ms(lambda: t in data):9.4f} ms")

実行結果(Python 3.11.15、Linux、2コアの検証用コンテナ。数値は環境によって変わります):

Python 3.11.15 / 要素数 1000000
先頭で見つかる
  any(ジェネレータ式)      0.0003 ms
  any([リスト内包表記])   14.7191 ms
  for文 + return           0.0001 ms
  in 演算子                0.0001 ms
中央で見つかる
  any(ジェネレータ式)     11.4067 ms
  any([リスト内包表記])   17.6947 ms
  for文 + return           5.2536 ms
  in 演算子                2.5307 ms
見つからない
  any(ジェネレータ式)     22.3012 ms
  any([リスト内包表記])   19.3807 ms
  for文 + return          10.6937 ms
  in 演算子                5.0907 ms
条件を満たす位置 any(ジェネレータ式) any(リスト内包表記) for文 + return in 演算子
先頭 0.0003 ms 14.7191 ms 0.0001 ms 0.0001 ms
中央 11.4067 ms 17.6947 ms 5.2536 ms 2.5307 ms
見つからない 22.3012 ms 19.3807 ms 10.6937 ms 5.0907 ms

この結果から読み取れることは次のとおりです。

  • 先頭近くで結果が決まる場合、ジェネレータ式はほぼ一瞬で終わります。 リスト内包表記は見つかる位置に関係なく、毎回100万件分のリストを作るので 15 ms 前後かかりました。
  • 最後まで見つからない場合は、リスト内包表記のほうがわずかに速い結果でした(22.3 ms と 19.4 ms)。ジェネレータ式は1件ずつ値を受け渡す手間がかかるためです。ただし差は小さく、リスト内包表記は判定用のリストを丸ごとメモリに作ります。
  • for文で書いた関数は、どの場合も any より速い結果でした。 それでも any は1行で意図が伝わるので、ここまでの差が問題になる場面以外では any で十分です。
  • 「ある値と等しいものがあるか」だけなら in 演算子が最も速く、書き方も最短です。

迷ったらジェネレータ式で書く、と覚えておけば十分です。 早く止まれる場面で大きな差が付き、止まれない場面でも差はわずかだからです。

途中打ち切りを生かす書き方のこつ

any(a(x) and b(x) for x in xs) のように条件を and でつなぐときは、軽い条件を先に、重い条件(正規表現、ファイルやネットワークへのアクセスなど)を後に書きます。 and は左側が偽なら右側を計算しないので、重い処理の回数を減らせます。

目的別のコピペ用逆引き表

よく使う判定を、番号つきでまとめました。下のコードはそのまま貼って動かせます。

番号 やりたいこと 書き方
1 1つでも満たす any(n > 40 for n in nums)
2 すべて満たす all(n > 0 for n in nums)
3 1つも満たさない not any(n < 0 for n in nums)
4 満たさないものが1つでもある not all(n % 2 == 0 for n in nums)
5 ちょうど1つ満たす sum(n % 2 == 1 for n in nums) == 1
6 2つ以上満たす、個数を数える sum(n % 2 == 0 for n in nums) >= 2
7 ある値を含む 15 in nums
8 複数の値をすべて含む、どれか含む all(x in nums for x in (4, 8))
9 空文字がある、すべて入力済み any(w == "" for w in words)、all(words)
10 文字列がキーワードのどれかを含む any(k in text for k in keywords)
11 すべての文字が数字 all(c.isdigit() for c in text)
12 昇順に並んでいる all(a <= b for a, b in zip(nums, nums[1:]))
13 すべて同じ値、重複がない all(x == nums[0] for x in nums)、len(set(nums)) == len(nums)
14 空ではなく、かつすべて満たす bool(nums) and all(n > 0 for n in nums)
15 Noneが1つもない、型が混ざっている all(x is not None for x in xs)
16 最初に条件を満たした要素を取り出す next((n for n in nums if n > 10), None)
17 判定しつつ見つけた値を残す any((hit := n) > 20 for n in nums)
nums = [4, 8, 15, 16, 23, 42]
words = ["apple", "", "cherry"]

# 1. 1つでも満たす
print(1, any(n > 40 for n in nums))
# 2. すべて満たす
print(2, all(n > 0 for n in nums))
# 3. 1つも満たさない(すべて満たさない)
print(3, not any(n < 0 for n in nums))
# 4. 満たさないものが1つでもある
print(4, not all(n % 2 == 0 for n in nums))
# 5. ちょうど1つ満たす
print(5, sum(n % 2 == 1 for n in nums) == 1)
# 6. 2つ以上満たす / 満たす個数を数える
print(6, sum(n % 2 == 0 for n in nums) >= 2, sum(n % 2 == 0 for n in nums))
# 7. ある値を含む(等しいかどうかだけなら in が最短)
print(7, 15 in nums)
# 8. 複数の値をすべて含む / どれか1つ含む
print(8, all(x in nums for x in (4, 8)), any(x in nums for x in (99, 42)))
# 9. 空文字が1つでもある / すべて入力済み
print(9, any(w == "" for w in words), all(words))
# 10. 文字列がキーワードのどれかを含む
print(10, any(k in "error: disk full" for k in ("error", "warn")))
# 11. すべての文字が数字(空文字は True になる点に注意)
print(11, all(c.isdigit() for c in "12345"), all(c.isdigit() for c in ""))
# 12. 昇順に並んでいる
print(12, all(a <= b for a, b in zip(nums, nums[1:])))
# 13. すべて同じ値 / 重複がない
print(13, all(x == nums[0] for x in nums), len(set(nums)) == len(nums))
# 14. 空ではなく、かつすべて満たす
print(14, bool(nums) and all(n > 0 for n in nums), bool([]) and all(n > 0 for n in []))
# 15. None が1つもない / 文字列が混ざっている
print(15, all(x is not None for x in [1, None]), any(isinstance(x, str) for x in [1, "a"]))
# 16. 最初に条件を満たした要素そのものがほしい
print(16, next((n for n in nums if n > 10), None), next((n for n in nums if n > 100), None))
# 17. 判定と同時に、見つかった値を変数に残す(Python 3.8 以降)
if any((hit := n) > 20 for n in nums):
    print(17, hit)

実行結果:

1 True
2 True
3 True
4 True
5 False
6 True 4
7 True
8 True True
9 True False
10 True
11 True True
12 True
13 False True
14 True False
15 False True
16 15 None
17 23

補足です。

  • 5と6の「個数を数える」 は、True が 1、False が 0 として足し算できる性質を使っています。sum は最後まで数えるので、途中打ち切りは効きません。
  • 3と4は書き換えができます。 「1つも満たさない」は「すべてが条件の逆を満たす」と同じなので、not any(n < 0 for n in nums) は all(n >= 0 for n in nums) とも書けます。読んで意味が伝わりやすいほうを選びます。
  • 11の空文字は、all の性質どおり True になります。空文字を除きたいときは text != "" and all(...) とするか、文字列全体に text.isdigit() を使います(空文字なら False)。
  • 16は any ではなく next を使います。 any が返すのは True / False だけなので、要素そのものがほしいときは next にジェネレータ式と既定値を渡します。
  • 17の :=(代入式) は Python 3.8 以降で使えます。any が True を返したときだけ、hit に見つかった値が入っています。

not any と not all の言い換え表

書き方 意味 同じ意味の別の書き方
any(P) 1つでも満たす not all(Pの逆)
all(P) すべて満たす not any(Pの逆)
not any(P) 1つも満たさない all(Pの逆)
not all(P) 満たさないものがある any(Pの逆)

辞書と文字列を渡したときの動き

リスト以外を渡したときの動きも確かめます。

stock = {"pen": 0, "note": 2, "": 3}

print(any(stock), all(stock))                    # キーを見る("" は偽)
print(any(stock.values()), all(stock.values()))  # 値を見る(0 は偽)
print(all(v >= 0 for v in stock.values()))       # 値に条件を付ける
print(any(k == "note" and v == 2 for k, v in stock.items()))  # キーと値の組

print(any("abc"), all("abc"))   # 文字列は1文字ずつ見る
print(any(""), all(""))         # 空文字は「空のイテラブル」
print(all("0"), all(["0", "False"]))  # 文字列の "0" や "False" は真

print(all([[], []]), any([[0]]))  # 入れ子:空リストは偽、[0] は空でないので真

実行結果:

True False
True False
True
True
True True
False True
True True
False True
渡すもの 判定される対象 気を付ける点
辞書そのもの キー 値を見たいときは .values() を付ける
辞書.values() 値 0 や空文字の値は偽
辞書.items() キーと値のタプル 条件式の中で for k, v in と分けて使う
文字列 1文字ずつ 1文字以上あればどの文字も真。空文字は空のイテラブル
集合・タプル・range 各要素 リストと同じ

辞書をそのまま渡すとキーを見る点が、いちばん気付きにくいところです。 「在庫が1つでもある品目があるか」を調べたいなら any(stock.values())、「すべての在庫が0以上か」なら all(v >= 0 for v in stock.values()) と書きます。

NumPyとpandasでの違い

NumPy の配列や pandas の Series・DataFrame には、専用の any と all が用意されています。組み込みの any / all とは動きが違うので、分けて覚えます。

NumPyの配列

import numpy as np

a = np.array([[1, 0],
              [3, 4]])

print(a.any(), a.all())      # 配列全体
print(a.all(axis=0))         # 列ごと
print(a.any(axis=1))         # 行ごと
print((a > 0).all(), np.any(a > 3))   # 条件を付ける

# 2次元配列を組み込みの any に渡すとエラーになる
try:
    any(a)
except ValueError as e:
    print("ValueError:", e)

# 空の配列・NaN
print(np.array([]).any(), np.array([]).all())
print(np.array([np.nan]).all())   # NaN は 0 ではないので真

実行結果(NumPy 2.4.4):

True False
[ True False]
[ True  True]
False True
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
False True
True
  • 配列には a.any() / a.all()(または np.any(a) / np.all(a))を使います。 axis=0 で列ごと、axis=1 で行ごとの結果が配列で返ります。
  • 2次元配列を組み込みの any に渡すと ValueError になります。 組み込みの any は行を1つずつ取り出して真偽を調べますが、要素が2つ以上ある配列は真偽を1つに決められないためです。エラー文にも a.any() か a.all() を使うよう書かれています。
  • 1次元配列なら組み込みの any でも動きますが、同じ100万件の配列で計測したところ、(arr == N - 1).any() が約 0.45 ms、any(arr == N - 1) が約 8.2 ms でした。配列には配列のメソッドを使うほうが速くなります。
  • NumPy のメソッドは配列全体をまとめて計算するので、途中打ち切りの考え方は組み込み関数とは別です。

pandasのSeriesとDataFrame

import numpy as np
import pandas as pd

s = pd.Series([1, 0, 3])
df = pd.DataFrame({"x": [1, 2, 3], "y": [0, 5, 6]})

print(s.any(), s.all())              # Series 全体
print((s > 0).all(), (s > 2).any())  # 条件を付ける
print(df.all())                      # 列ごと(既定は axis=0)
print(df.any(axis=1))                # 行ごと
print((df > 0).all(axis=None))       # 表全体で1つの結果

# 組み込みの any / all に DataFrame を渡すと「列名」を見る
print(any(df), all(df), list(df))

# 空の Series と NaN
e = pd.Series([], dtype=float)
print(e.any(), e.all())
n = pd.Series([np.nan, np.nan])
print(n.any(), n.all())                              # 既定は skipna=True
print(n.any(skipna=False), n.all(skipna=False))

# if に Series をそのまま渡すとエラーになる
try:
    if s > 0:
        pass
except ValueError as e:
    print("ValueError:", e)

実行結果(pandas 3.0.2):

True False
False True
x     True
y    False
dtype: bool
0    True
1    True
2    True
dtype: bool
False
True True ['x', 'y']
False True
False True
True True
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
  • df.all() は列ごとの結果を返します(既定は axis=0)。行ごとなら axis=1、表全体で1つの結果がほしいときは axis=None を指定します。
  • 組み込みの any(df) は列名を見ます。 DataFrame を for文で回すと列名が取り出されるためで、中身の値は判定されません。DataFrame には必ず .any() / .all() メソッドを使います。
  • NaN は既定で読み飛ばされます(skipna=True)。すべて NaN の Series は、空の Series と同じく any が False、all が True になりました。skipna=False を指定すると NaN は 0 ではない値として真に数えられます。
  • if に Series をそのまま渡すと ValueError になります。 if (s > 0).all(): や if (s > 0).any(): のように、どちらの意味かを明示します。

組み込み・NumPy・pandasの比較表

項目 組み込み any / all NumPy pandas
書き方 any(xs) a.any()、np.any(a) s.any()、df.any()
条件の付け方 any(x > 0 for x in xs) (a > 0).any() (s > 0).any()
戻り値 True / False NumPyの真偽値、または配列 真偽値、または Series
行・列ごとの判定 なし axis=0、axis=1 axis=0、axis=1、axis=None
空のとき any は False、all は True 同じ 同じ
NaN の扱い 真 真 既定では読み飛ばす
途中打ち切り あり 全体をまとめて計算 全体をまとめて計算

つまずきやすい点とエラー文

実際に出るエラー文と、気付きにくい動きを再現します。

nums = [4, 8, 15]

# 1. イテラブルでないものを渡す
try:
    any(5)
except TypeError as e:
    print("TypeError:", e)

# 2. 値を2つ並べて渡す
try:
    any(1, 2)
except TypeError as e:
    print("TypeError:", e)

# 3. ジェネレータ式そのものを if に渡す(any を付け忘れた形)
gen = (n > 100 for n in nums)
print(bool(gen))                       # 中身に関係なく True
print(bool([n > 100 for n in nums]))   # 空でないリストなので True
print(any(n > 100 for n in nums))      # 正しくは any で包む

# 4. イテレータは読んだ分だけ進む
it = iter([0, 0, 5, 0, 7])
print(any(it), list(it))

実行結果:

TypeError: 'int' object is not iterable
TypeError: any() takes exactly one argument (2 given)
True
True
False
True [0, 7]
症状 原因 直し方
'int' object is not iterable 数値など、for文で回せないものを渡した リストやタプルに入れて渡す
any() takes exactly one argument (2 given) 値をカンマで並べて渡した any([a, b]) のように1つにまとめる。2つ程度なら a or b で足りる
if の条件がいつも True になる any / all を付けずにジェネレータ式やリストを if に渡した if any(...) と包む
2回目の判定結果が変わる イテレータやジェネレータを使い回した リストにしてから渡すか、毎回作り直す
The truth value of an array ... is ambiguous NumPy配列や Series を組み込みの any や if に渡した .any() / .all() メソッドを使う

4つ目は少しわかりにくいので補足します。iter() で作ったイテレータやジェネレータは、一度読んだ要素を戻せません。上の例では any が 5 を見つけた時点で止まり、残りの [0, 7] だけがイテレータに残りました。同じデータを何度も判定するときは、リストのまま持っておきます。

直す前と直した後

# 直す前:フラグ変数と for 文
has_error = False
for line in lines:
    if "ERROR" in line:
        has_error = True
        break
if has_error:
    notify()

# 直した後:any で1行に
if any("ERROR" in line for line in lines):
    notify()
# 直す前:リスト内包表記(全件を計算してから判定)
if all([is_valid(row) for row in rows]):
    save(rows)

# 直した後:ジェネレータ式(偽が見つかった時点で止まる)
if all(is_valid(row) for row in rows):
    save(rows)

この2つのコードは形の説明用で、lines や rows、notify などは定義していないため、このままでは実行していません(未実行)。

どの書き方を選ぶかの判断表

状況 選ぶ書き方 理由
True / False だけがほしい any / all + ジェネレータ式 短く、途中で止まる
ある値と等しい要素があるか in 演算子 最も短く、計測でも最も速い
条件を満たす要素そのものがほしい next(ジェネレータ式, None) any は真偽しか返さない
条件を満たす個数がほしい sum(条件 for x in xs) True を1として数えられる
条件を満たす要素を全部ほしい リスト内包表記 [x for x in xs if 条件] 結果をリストで受け取れる
判定の途中で別の処理もしたい for文 + break 処理を自由に書ける
NumPy配列・pandas .any() / .all() メソッド 配列全体をまとめて計算できる
空のときは False にしたい bool(xs) and all(...) all は空で True を返すため

よくある質問

Q. anyとallは、orやandと何が違いますか? A. 意味は同じで、扱える個数が違います。a or b or c は値を式の中に並べて書きますが、any はリストなど個数が決まっていないものをまとめて判定できます。また、or と and は真偽値ではなく値そのものを返す(0 or "x" は "x")のに対し、any と all は必ず True か False を返します。

Q. ジェネレータ式とリスト内包表記のどちらで書けばよいですか? A. 基本はジェネレータ式(角かっこなし)です。今回の計測では、先頭で結果が決まる場合にジェネレータ式が 0.0003 ms、リスト内包表記が約 14.7 ms でした。最後まで見つからない場合はリスト内包表記がわずかに速い結果でしたが、差は小さく、判定用のリストをメモリに作らないジェネレータ式のほうが扱いやすくなります。

Q. all([])がTrueになるのは不具合ではないのですか? A. 仕様です。all は「偽の要素が見つかったら False」を返す関数で、空なら偽の要素が見つからないので True になります。空のときに False にしたい場合は bool(xs) and all(...) と書きます。

Q. 条件を満たした要素を取り出したいときはどうしますか? A. any ではなく next((x for x in xs if 条件), None) を使います。見つからなかったときは2つ目の引数(ここでは None)が返ります。判定と同時に値を残したい場合は、Python 3.8 以降の代入式を使って any((hit := x) > 20 for x in xs) と書けます。

まとめ

  • any は「1つでも真なら True」、all は「すべて真なら True」。空を渡すと any は False、all は True になります。
  • 0、0.0、空文字、None、空のリストは偽。文字列の "0" や "False" は真として扱われます。
  • all([]) が True なのは「偽の要素が1つもない」から。空を除きたいときは bool(xs) and all(...) と書きます。
  • かっこの中はジェネレータ式で書く。先頭で結果が決まる場合、リスト内包表記との差は 0.0003 ms と約 14.7 ms でした。
  • 「1つも満たさない」は not any、「ちょうど1つ」は sum(...) == 1、「要素そのもの」は next を使います。
  • 辞書をそのまま渡すとキーを見る。値を見るときは .values() を付けます。
  • NumPy と pandas には .any() / .all() メソッドを使う。pandas は既定で NaN を読み飛ばします。

参考

  • Python 公式ドキュメント「組み込み関数」(all、any の説明と同等のコード): https://docs.python.org/ja/3/library/functions.html

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?