Pythonのany関数とall関数はどのように機能しますか?


225

any()all()Pythonの組み込み関数がどのように機能するかを理解しようとしています。

タプルを比較して、値が異なる場合はそれが返さTrueれ、それらがすべて同じである場合は返されるようにしていFalseます。この場合、彼らはどのようにして[False、False、False]を返しますか?

dですdefaultdict(list)

print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]

私の知る限り、これは出力するはずです

# [False, True, False]

(1,1)は同じなので、(5,6)は異なり、(0,0)は同じです。

すべてのタプルでfalseと評価されるのはなぜですか?


4
any(iterable):Truthyオブジェクトが最初に検出されたときにtrueを返し、それ以外の場合はfalseを返します。all(iterable):偽のオブジェクトに最初に遭遇したときにflaseを返し、そうでない場合はtrueを返します。
shadow0359 2017年

回答:


375

あなたはおおよその考えることができるanyall論理的な一連のorand、それぞれの演算子。

どれか

any少なくとも1つの要素がTruthy であるTrueとき戻ります。真理値テストについてお読みください

すべて

allすべての要素が真実であるTrue場合にのみ戻ります。

真理値表

+-----------------------------------------+---------+---------+
|                                         |   any   |   all   |
+-----------------------------------------+---------+---------+
| All Truthy values                       |  True   |  True   |
+-----------------------------------------+---------+---------+
| All Falsy values                        |  False  |  False  |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| Empty Iterable                          |  False  |  True   |
+-----------------------------------------+---------+---------+

注1:空の反復可能なケースは、次のように公式ドキュメントで説明されています

any

Trueイテラブルのいずれかの要素がtrueの場合に返します。イテラブルが空の場合は、False

どの要素も真ではないためFalse、この場合は戻ります。

all

Trueイテラブルのすべての要素がtrueの場合(またはイテラブルが空の場合)に戻ります。

どの要素も偽ではないためTrue、この場合は戻ります。


注2:

知るためのもう一つの重要なことanyallされ、それが実行、彼らは結果を知った瞬間短絡なります。利点は、イテラブル全体を消費する必要がないことです。例えば、

>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]

ここで(not (i % 6) for i in range(1, 10))は、True1と9の現在の数が6の倍数である場合に返されるジェネレータ式です。をany反復しmultiples_of_6、に出会うと6、Truthy値を見つけるため、すぐに戻りTrue、残りのmultiples_of_6は反復されません。これはlist(multiples_of_6)、印刷したときに表示されるもので78との結果です9

この優れたものは、この回答で非常に巧妙に使用されています


この基本的な理解があれば、コードを見ると、

any(x) and not all(x)

これは、値の少なくとも1つがTruthyであるが、すべてではないことを確認します。それが戻ってきた理由[False, False, False]です。両方の数値が同じでないかどうかを本当に確認したい場合は、

print [x[0] != x[1] for x in zip(*d['Drd2'])]

@anyone:空のリストに対してTrueを返す場合を除いてすべてを使用する必要がある場合は、どうすればよいですか?リストが空の場合にTrueを与えることの背後にある論理を理解できません... all([])== Trueを意味します
JavaSa

1
@JavaSaリストが空かどうかを明示的に確認できます。のようなものbool(data) and all(...)がうまくいくと思います。
thefourtheye

43

Python anyall関数はどのように機能しますか?

anyそしてall、イテラブルを取りTrue、要素のいずれかおよびすべてが(それぞれ)である場合は返しますTrue

>>> any([0, 0.0, False, (), '0']), all([1, 0.0001, True, (False,)])
(True, True)            #   ^^^-- truthy non-empty string
>>> any([0, 0.0, False, (), '']), all([1, 0.0001, True, (False,), {}])
(False, False)                                                #   ^^-- falsey

イテラブルが空の場合、をany返しFalse、をall返しますTrue

>>> any([]), all([])
(False, True)

今日は、クラスの生徒にデモallany行っていました。空のイテラブルの戻り値について、ほとんど混乱していました。このように説明すると、多くの電球が点灯しました。

ショートカット動作

彼らanyallはどちらも、評価を停止できる条件を探します。私が最初に挙げた例では、リスト全体の各要素のブール値を評価する必要がありました。

(リストリテラル自体は遅延評価されないことに注意してください- イテレーターでそれを取得できますが、これは単なる説明目的です。)

以下は、あらゆるもののPython実装です。

def any(iterable):
    for i in iterable:
        if i:
            return True
    return False # for an empty iterable, any returns False!

def all(iterable):
    for i in iterable:
        if not i:
            return False
    return True  # for an empty iterable, all returns True!

もちろん、実際の実装はCで記述されており、はるかに高いパフォーマンスを発揮しますが、上記のコードを置き換えると、この(またはその他の)回答のコードに対して同じ結果を得ることができます。

all

all要素がであるかどうかを確認しFalse(それが返される可能性があるFalse)、要素がないTrue場合はを返しますFalse

>>> all([1, 2, 3, 4])                 # has to test to the end!
True
>>> all([0, 1, 2, 3, 4])              # 0 is False in a boolean context!
False  # ^--stops here!
>>> all([])
True   # gets to end, so True!

any

any動作する方法は、要素があるかどうかをチェックすることですTrue(そのため、True), then it returnsFalse if none of them wereTrue` を返すことができます)。

>>> any([0, 0.0, '', (), [], {}])     # has to test to the end!
False
>>> any([1, 0, 0.0, '', (), [], {}])  # 1 is True in a boolean context!
True   # ^--stops here!
>>> any([])
False   # gets to end, so False!

近道の行動を覚えておけば、真理値表を参照しなくても直感的に理解できると思います。

証拠allanyショートカット:

まず、noisy_iteratorを作成します。

def noisy_iterator(iterable):
    for i in iterable:
        print('yielding ' + repr(i))
        yield i

次に、例を使用して、リストを騒々しく反復します。

>>> all(noisy_iterator([1, 2, 3, 4]))
yielding 1
yielding 2
yielding 3
yielding 4
True
>>> all(noisy_iterator([0, 1, 2, 3, 4]))
yielding 0
False

私たちは見ることができますall最初はFalseブールチェックの停止を。

そしてany最初の真のブールチェックで停止します:

>>> any(noisy_iterator([0, 0.0, '', (), [], {}]))
yielding 0
yielding 0.0
yielding ''
yielding ()
yielding []
yielding {}
False
>>> any(noisy_iterator([1, 0, 0.0, '', (), [], {}]))
yielding 1
True

起源

上記を確認するためにソースを見てみましょう。

ここにソースがありanyます:

static PyObject *
builtin_any(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp > 0) {
            Py_DECREF(it);
            Py_RETURN_TRUE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_FALSE;
}

そしてここにソースがありallます:

static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp == 0) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_TRUE;
}

1
注:これは、数学の述語「すべて」と「存在」と一致しています。"FOR ALL"と "FOR ANY"は他のコンテキストでは同義語である可能性があります... en.wikipedia.org/wiki/List_of_logic_symbols
mcoolive

1
@ thanos.aありますPython/bltinmodule.c-上記に追加しました。
アーロンホール

14

私はこれが古いことを知っていますが、これらの関数がコードでどのように見えるかを示すことが役立つと思いました。これは実際にロジックを示しており、テキストやテーブルIMOよりも優れています。実際には、純粋なPythonではなくCで実装されていますが、これらは同等です。

def any(iterable):
    for item in iterable:
        if item:
            return True
    return False

def all(iterable):
    for item in iterable:
        if not item:
            return False
    return True

特に、空のイテラブルの結果は特別なケースではなく、自然な結果であることがわかります。また、短絡動作も確認できます。短絡が起こらないようにすることは実際にはより多くの作業になるでしょう。

Guido van Rossum(Pythonの作成者)が最初にany()andを追加することを提案したときall()、彼は上記のコードスニペットを正確に投稿するだけでそれらを説明しました。


10

あなたが質問している問題のコードは、ここで与えられ私の答えから来ています。これは、複数のビット配列、つまり1およびのコレクションを比較する問題を解決するためのもの0です。

anyそしてallあなたは値の「truthiness」に頼ることができたときに便利です-ブール値のコンテキストで自分の価値、すなわち。1 Trueと0はFalse、その答えを活用した便利さです。5もたまたまTrueですので、それを可能な入力に混ぜると...まあ。動作しません。

代わりに次のようなことをすることができます:

[len(set(x)) > 1 for x in zip(*d['Drd2'])]

以前の答えの美学は欠けています(私はの外観が本当に好きでしたany(x) and not all(x))が、それは仕事を成し遂げます。


コルベールの影響力はCS / CEに及んでいます:en.wikipedia.org/wiki/Truthiness?私たちはファジーロジックを話しているのですか?:D
Geof Sawaya 2017

OPがTrue値が異なる場合に要求したように、セットの長さは1ではなく2にする必要があります
wombatonfire

@wombatonfireハハグッドキャッチ。7歳の答えを調整しました:)
roippi

良い答えは年を取りません:)セットでの素晴らしいアプローチ。
ウォンバトンファイヤー

7
>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True


1

コンセプトは簡単です:

M =[(1, 1), (5, 6), (0, 0)]

1) print([any(x) for x in M])
[True, True, False] #only the last tuple does not have any true element

2) print([all(x) for x in M])
[True, True, False] #all elements of the last tuple are not true

3) print([not all(x) for x in M])
[False, False, True] #NOT operator applied to 2)

4) print([any(x)  and not all(x) for x in M])
[False, False, False] #AND operator applied to 1) and 3)
# if we had M =[(1, 1), (5, 6), (1, 0)], we could get [False, False, True]  in 4)
# because the last tuple satisfies both conditions: any of its elements is TRUE 
#and not all elements are TRUE 

0
list = [1,1,1,0]
print(any(list)) # will return True because there is  1 or True exists
print(all(list)) # will return False because there is a 0 or False exists
return all(a % i for i in range(3, int(a ** 0.5) + 1)) # when number is divisible it will return False else return True but the whole statement is False .
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.