閉じる

【Python】anyとallの違いと使い分け|リスト条件判定を最速で書く方法

Pythonでリストや条件の判定を書く時、if文を何重にもネストしてしまい、後から読み返したときによく分からなくなってしまうことはないでしょうか。

このような場面で、anyとallを正しく使いこなせると、コードが短く・速く・読みやすくなります。

本記事では、Pythonのanyとallの違いと使い分け方を、実務レベルのサンプルコードとともに詳しく解説します。

anyとallとは?Pythonの基本動作を整理

anyとは

anyは「1つでも真があれば真」になる関数です。

イテラブル(リストやタプル、ジェネレータなど)を受け取り、その中の要素に1つでも真(True)があればTrueを返します。

すべて偽(False)ならFalseを返します。

anyの基本的な使い方

Python
# anyの基本動作を確認するサンプル

values1 = [False, False, True, False]
values2 = [0, 0, 0]        # 数値は0がFalse扱い、それ以外はTrue扱い
values3 = ["", "abc", ""]  # 空文字はFalse扱い、非空文字列はTrue扱い

print(any(values1))  # どれか1つでもTrueがあればTrue
print(any(values2))  # すべて0なのでFalse
print(any(values3))  # "abc"がTrue扱いなのでTrue
実行結果
True
False
True

このように、anyは「条件を1つでも満たす要素があるか」を判定する場面でとてもよく使われます。

allとは

allは「すべて真なら真」になる関数です。

イテラブルの中の要素がすべて真である場合にTrueを返し、1つでも偽が混ざっていればFalseを返します。

allの基本的な使い方

Python
# allの基本動作を確認するサンプル

values1 = [True, True, True]
values2 = [True, False, True]
values3 = [1, 2, 3]      # 0でない数値はTrue扱い
values4 = ["a", ""]      # 空文字がFalse扱い

print(all(values1))  # すべてTrueなのでTrue
print(all(values2))  # Falseを含むのでFalse
print(all(values3))  # すべて0以外なのでTrue
print(all(values4))  # ""がFalse扱いなのでFalse
実行結果
True
False
True
False

allは「複数の条件をすべて満たしているか」を1行で確認するのに向いています。

anyとallの戻り値と空のリストの扱い

anyとallはともに戻り値は必ず真偽値(TrueFalse)です。

ただし、空のリストや空のイテラブルに対する挙動が異なる点に注意が必要です。

空のリストのときの挙動

Pythonの仕様は次のようになっています。

  • any([]) は False
    「真である要素が1つも存在しない」とみなされます。
  • all([]) は True
    「偽である要素も1つも存在しない」ため、「すべての要素が真である」という条件は空集合に対しては真とみなされます(数学の論理と同じ考え方です)。

挙動を確認してみます。

Python
# 空のリストやタプルに対するanyとallの挙動

empty_list = []
empty_tuple = ()

print(any(empty_list), all(empty_list))
print(any(empty_tuple), all(empty_tuple))
実行結果
False True
False True

特にバリデーションやフィルタ処理では、この空のときの挙動を知らないとバグの原因になりやすいので、必ず押さえておくと安心です。

anyとallの違いを具体例で理解

if文との比較

anyとallが便利とは聞いても、実際のif文とどう違うのかが分からないと使いにくいかもしれません。

ここでは、従来のif文と比較しながら考えてみます。

anyをif文で書いた場合との比較

例えば、「値が10より大きい、または5未満、または偶数のどれかならOK」という条件を考えます。

Python
x = 7

# 従来のif文(論理演算子でつなぐ)
if (x > 10) or (x < 5) or (x % 2 == 0):
    print("条件を1つ以上満たしています")

同じ意味をanyで書くと次のようになります。

Python
x = 7

# anyを使った場合
conditions = [
    x > 10,
    x < 5,
    x % 2 == 0,
]

if any(conditions):
    print("条件を1つ以上満たしています")

条件の種類が増えたとき、論理演算子でつなぐよりも、any/allに真偽値のリストを渡す方が、一覧性と拡張性が高いことが分かります。

ネストした条件式よりany・allが読みやすいケース

if文のネスト(入れ子)が深くなると、どの条件がどこに対応しているのか分かりづらくなります。

anyとallを使うと、ネストを浅く抑えられるケースが多くあります。

ネストした条件の書き換え例

「ユーザーが有効かどうか」を判定する例を考えます。

条件は次のようにします。

  • アカウントが有効である
  • かつ、次のいずれかが真
    • 管理者である
    • 支払い済みのユーザーである
    • 特別な招待コードを持っている

ネストしたif文で書くと、次のようになりがちです。

Python
user = {
    "is_active": True,
    "is_admin": False,
    "is_paid": True,
    "has_invite_code": False,
}

# ネストしたif文の例
if user["is_active"]:
    if user["is_admin"] or user["is_paid"] or user["has_invite_code"]:
        print("アクセスを許可します")

any/allを使うと、条件の構造がより明示的になります。

Python
user = {
    "is_active": True,
    "is_admin": False,
    "is_paid": True,
    "has_invite_code": False,
}

can_access = all([
    user["is_active"],  # まずアカウントが有効であること
    any([               # さらに、以下のいずれかを満たすこと
        user["is_admin"],
        user["is_paid"],
        user["has_invite_code"],
    ]),
])

if can_access:
    print("アクセスを許可します")
実行結果
アクセスを許可します

「全体としてはall、その中の一部がany」というように、ビジネスルールの構造をコード上でも表現しやすくなる点が大きなメリットです。

真偽値以外の値(数値・文字列)を評価する挙動

anyとallは、リストの要素が真偽値でなくても動作します。

Pythonには「真っぽい値」「偽っぽい値」という考え方があり、それに従って評価されます。

数値と文字列の例

Python
values = [0, 1, 2, -1, 0.0]
texts = ["", "hello", " ", "0"]

print(any(values))  # 0以外の数値があるのでTrue
print(all(values))  # 0が含まれるのでFalse

print(any(texts))   # 非空文字列があるのでTrue
print(all(texts))   # ""が含まれるのでFalse
実行結果
True
False
True
False

このように、any/allは「要素をboolに変換した結果」で判定を行うことを意識しておくと、数値・文字列・リストなどを直接渡したときにも挙動を予測しやすくなります。

リスト条件判定を最速で書くany・allの使い方

ここからは、anyとallを使ってリストの条件判定を短く・速く書く具体的なパターンを見ていきます。

リスト内包表記とany・allの組み合わせ

any/allは、リスト内包表記やジェネレータ式と組み合わせると威力を発揮します。

条件を満たすかどうかだけ知りたい場合は、まずリストを作らずにジェネレータ式を渡すのが効率的です。

例: リストの中に偶数が1つでもあるか

Python
numbers = [1, 3, 5, 8, 11]

# ジェネレータ式をanyに渡す例
has_even = any(n % 2 == 0 for n in numbers)

print(has_even)
実行結果
True

ここで(n % 2 == 0 for n in numbers)は、条件を満たすかどうかだけを順に評価するジェネレータ式です。

anyは、Trueになった時点で後続の要素を調べずに止まるため、高速かつ省メモリで判定できます。

複数条件をallでまとめて判定するパターン

allは、1つの対象に対して複数の条件がすべて満たされているかを判定するのに向いています。

例: 文字列が「長さ8文字以上」「数字を含む」「英字を含む」かどうか

Python
def is_strong_password(password: str) -> bool:
    # 各条件を個別に定義
    length_ok = len(password) >= 8
    has_digit = any(ch.isdigit() for ch in password)
    has_alpha = any(ch.isalpha() for ch in password)

    # すべての条件を満たしているかをallでまとめて判定
    return all([
        length_ok,
        has_digit,
        has_alpha,
    ])


print(is_strong_password("abc123"))       # 長さ不足 → False
print(is_strong_password("abcd1234"))     # 条件をすべて満たす → True
print(is_strong_password("abcdefgh"))     # 数字なし → False
実行結果
False
True
False

このように、複数のチェック結果(真偽値)を最後にallで束ねると、複雑な条件でも見通し良く書けます。

1つでも条件を満たすかをanyで判定するパターン

anyは、「どれか1つでもOKならよい」という条件の時にとても自然に使えます。

例: 禁止ワードを含むかどうか

Python
ng_words = ["禁止", "違法", "暴力"]

def contains_ng_word(text: str) -> bool:
    # どれか1つでも禁止ワードが含まれていればTrue
    return any(word in text for word in ng_words)


print(contains_ng_word("これは合法的な文章です"))       # False
print(contains_ng_word("これは違法なコンテンツです"))   # True
実行結果
False
True

forループで順にifを回しながら判定するよりも、anyを使うことで意図が明確になり、コード行数も減らせます。

ネストループをany・allで置き換えて高速化する

ネストしたforループで条件を探す処理は、any/allを使うことで早期終了しやすくなり、結果として高速化できる場合があります。

例: 2次元リストの中に特定の値が存在するか

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

target = 5

# 従来の二重ループでの探索
def contains_value_loop(matrix, target):
    for row in matrix:
        for value in row:
            if value == target:
                return True
    return False

# anyをネストして書く方法
def contains_value_any(matrix, target):
    # 各行(row)にtargetを含むかどうかをanyで判定し、
    # さらにそれを行全体に対してanyでまとめる
    return any(
        any(value == target for value in row)
        for row in matrix
    )

print(contains_value_loop(matrix, target))
print(contains_value_any(matrix, target))
実行結果
True
True

どちらも意味は同じですが、contains_value_anyの方が「anyの2階層構造」として読みやすく、条件に集中しやすい書き方になっています。

実務で役立つany・allの活用パターン

ここからは、実務でany/allが特に役立つ具体的なシーンを取り上げます。

バリデーション(入力チェック)でのany・all活用

フォーム入力やAPIのパラメータチェックなどでは、複数の入力項目を評価する場面が頻出します。

any/allを使うとチェックロジックを短く・漏れなく記述できます。

例: ユーザー登録フォームの簡易チェック

Python
def validate_user_form(name: str, email: str, age: int | None) -> list[str]:
    errors = []

    # 必須チェックなどの個別判定
    if not name:
        errors.append("名前は必須です")
    if not email or "@" not in email:
        errors.append("メールアドレスの形式が不正です")
    if age is None or age <= 0:
        errors.append("年齢は正の数で入力してください")

    return errors


def is_form_valid(name: str, email: str, age: int | None) -> bool:
    errors = validate_user_form(name, email, age)
    # エラーが1つもなければ有効
    return all([
        # エラーリストが空であることをallに含めて判定しているイメージ
        len(errors) == 0,
    ])


# 実際の利用例
name = "山田太郎"
email = "taro@example.com"
age = 30

if is_form_valid(name, email, age):
    print("登録処理を続行します")
else:
    print("入力内容を確認してください")
実行結果
登録処理を続行します

もう少し直球に書くなら、len(errors) == 0だけで十分ですが、複数の条件を足していく前提なら、allで束ねる前提で書いておくと拡張しやすいです。

データクレンジング・フィルタリングでの条件判定

データ分析やログ処理などで、リストやレコードの中から条件に合うものだけを抽出したい場面はとても多いです。

この時、any/allはfilterやリスト内包表記と相性が良いです。

例: いくつかの条件を満たすレコードだけを抽出

Python
users = [
    {"name": "A", "age": 20, "active": True},
    {"name": "B", "age": 15, "active": True},
    {"name": "C", "age": 30, "active": False},
    {"name": "D", "age": 25, "active": True},
]

# 条件:
# - activeがTrueである
# - かつ、年齢が18歳以上である
valid_users = [
    user
    for user in users
    if all([
        user["active"],
        user["age"] >= 18,
    ])
]

print(valid_users)
実行結果
[{'name': 'A', 'age': 20, 'active': True}, {'name': 'D', 'age': 25, 'active': True}]

また、「NG条件に1つでも当てはまるか」をanyで書いて、notを使って弾くこともよくあります。

Python
# NG条件:
# - 年齢が18未満
# - activeがFalse

cleaned_users = [
    user
    for user in users
    if not any([
        user["age"] < 18,
        not user["active"],
    ])
]

print(cleaned_users)
実行結果
[{'name': 'A', 'age': 20, 'active': True}, {'name': 'D', 'age': 25, 'active': True}]

「条件を満たすものを残す」「条件に引っかかるものを除外する」という2種類のフィルタリングを、any/allとnotを組み合わせて表現できます。

例外処理やガード節でのシンプルな条件記述

実務では、関数の冒頭で「この条件を満たさない場合はすぐに抜ける」ガード節を多用します。

any/allを使うと、複数のNG条件をまとめてすっきり書けるようになります。

例: 不正な引数なら早めにエラーにする

Python
def process_order(quantity: int, price: float):
    # NG条件:
    # - quantityが0以下
    # - priceが0未満
    if any([
        quantity <= 0,
        price < 0,
    ]):
        raise ValueError("数量と価格が不正です")

    total = quantity * price
    print(f"合計金額: {total}円")


# 有効なケース
process_order(3, 100.0)

# 無効なケース(コメントを外すと例外が発生)
# process_order(0, 100.0)
実行結果
合計金額: 300.0円

また、「あるリソースが利用可能かどうか」を複数条件で判定する時にもallが使えます。

Python
def can_start_service(db_connected: bool, cache_ready: bool, config_loaded: bool) -> bool:
    return all([
        db_connected,
        cache_ready,
        config_loaded,
    ])


status = can_start_service(
    db_connected=True,
    cache_ready=True,
    config_loaded=False,
)

if not status:
    print("サービスを開始できません。依存するリソースを確認してください。")
実行結果
サービスを開始できません。依存するリソースを確認してください。

ガード節や前提条件チェックにany/allを用いると、「前提が崩れているか」「前提が満たされているか」を1行で明確に表現できます。

まとめ

anyとallは、Pythonに標準で用意されているシンプルな関数ですが、条件判定を「短く・読みやすく・高速に」書くための強力なツールです。

anyは「1つでも真ならTrue」、allは「すべて真ならTrue」であり、空のイテラブルに対する挙動(anyはFalse、allはTrue)も押さえておくことが重要です。

リスト内包表記やジェネレータ式と組み合わせることで、ネストしたif文や二重ループをすっきり書き換えることができ、バリデーション、データクレンジング、例外処理など実務でも活躍の場が多くあります。

日々のコードの中で「複数条件」「リストの中の条件判定」が出てきたら、まずanyとallで書けないかを検討してみると、コードの質が一段と向上します。

コーディングテクニック

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!