Python 的 any 和 all 函数是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19389490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:38:31  来源:igfitidea点击:

How do Python's any and all functions work?

python

提问by O.rka

I'm trying to understand how the any()and all()Python built-in functions work.

我试图了解any()all()Python 内置函数是如何工作的。

I'm trying to compare the tuples so that if any value is different then it will return Trueand if they are all the same it will return False. How are they working in this case to return [False, False, False]?

我正在尝试比较元组,以便如果任何值不同,则它将返回True,如果它们都相同,则返回False。在这种情况下,他们如何工作以返回 [False, False, False]?

dis a defaultdict(list).

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]

To my knowledge, this should output

据我所知,这应该输出

# [False, True, False]

since (1,1) are the same, (5,6) are different, and (0,0) are the same.

因为 (1,1) 相同,(5,6) 不同,(0,0) 相同。

Why is it evaluating to False for all tuples?

为什么它对所有元组都评估为 False?

采纳答案by thefourtheye

You can roughly think of anyand allas series of logical orand andoperators, respectively.

您可以粗略地将any和 分别all视为一系列逻辑orand运算符。

any

任何

anywill return Truewhen at least one of the elementsis Truthy. Read about Truth Value Testing.

anyTrue至少一个元素为Truthy时将返回。阅读真值测试。

all

全部

allwill return Trueonly when all the elementsare Truthy.

allTrue只有当所有元素都为Truthy时才会返回。

Truth table

真值表

+-----------------------------------------+---------+---------+
|                                         |   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   |
+-----------------------------------------+---------+---------+

Note 1:The empty iterable case is explained in the official documentation, like this

注1:空的iterable case在官方文档中有说明,像这样

any

any

Return Trueif any element of the iterable is true. If the iterable is empty, return False

True如果迭代的任何元素为真,则返回。如果可迭代对象为空,则返回False

Since none of the elements are true, it returns Falsein this case.

由于所有元素都不为真,因此False在这种情况下返回。

all

all

Return Trueif all elements of the iterable are true (or if the iterable is empty).

返回True如果迭代的所有元素都是真(或者,如果可迭代为空)。

Since none of the elements are false, it returns Truein this case.

由于没有一个元素是假的,它True在这种情况下返回。



Note 2:

笔记2:

Another important thing to know about anyand allis, it will short-circuit the execution, the moment they know the result. The advantage is, entire iterable need not be consumed. For example,

另一个重要的事情了解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]

Here, (not (i % 6) for i in range(1, 10))is a generator expression which returns Trueif the current number within 1 and 9 is a multiple of 6. anyiterates the multiples_of_6and when it meets 6, it finds a Truthy value, so it immediately returns True, and rest of the multiples_of_6is not iterated. That is what we see when we print list(multiples_of_6), the result of 7, 8and 9.

这里,(not (i % 6) for i in range(1, 10))是一个生成器表达式,True如果 1 和 9 内的当前数字是 6 的倍数,则返回。any迭代multiples_of_6,当遇到 时6,它找到一个真值,所以它立即返回True,其余的multiples_of_6不迭代。这就是我们在打印时看到list(multiples_of_6)78和的结果9

This excellent thing is used very cleverly in this answer.

这个优秀的东西在这个答案中使用得非常巧妙。



With this basic understanding, if we look at your code, you do

有了这个基本的了解,如果我们查看您的代码,您就会

any(x) and not all(x)

which makes sure that, atleast one of the values is Truthy but not all of them. That is why it is returning [False, False, False]. If you really wanted to check if both the numbers are not the same,

这确保至少其中一个值是Truthy,但不是全部。这就是它返回的原因[False, False, False]。如果你真的想检查两个数字是否不一样,

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

回答by roippi

The code in question you're asking about comes from my answer given here. It was intended to solve the problem of comparing multiple bit arrays - i.e. collections of 1and 0.

你问的有问题的代码来自我在这里给出的答案。它旨在解决比较多个位数组的问题 - 即1和 的集合0

anyand allare useful when you can rely on the "truthiness" of values - i.e. their value in a boolean context. 1 is Trueand 0 is False, a convenience which that answer leveraged. 5 happens to also be True, so when you mix that into your possible inputs... well. Doesn't work.

any并且all当您可以依赖值的“真实性”时很有用 - 即它们在布尔上下文中的值。1 是True0 是False,这是该答案利用的便利。5 恰好也是True,所以当你把它混合到你可能的输入中时......好吧。不起作用。

You could instead do something like this:

你可以做这样的事情:

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

It lacks the aesthetics of the previous answer (I reallyliked the look of any(x) and not all(x)), but it gets the job done.

它缺乏上一个答案的美感(我真的很喜欢 的外观any(x) and not all(x)),但它完成了工作。

回答by Aaron Hall

How do Python's anyand allfunctions work?

Pythonanyall函数是如何工作的?

anyand alltake iterables and return Trueif any and all (respectively) of the elements are True.

any如果任何和所有(分别)元素是,则all取可迭代对象并返回。TrueTrue

>>> 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

If the iterables are empty, anyreturns False, and allreturns True.

如果可迭代对象为空,则any返回False,并all返回True

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

I was demonstrating alland anyfor students in class today. They were mostly confused about the return values for empty iterables. Explaining it this way caused a lot of lightbulbs to turn on.

我演示allany为今天学生上课。他们大多对空迭代的返回值感到困惑。以这种方式解释它会导致许多灯泡亮起。

Shortcutting behavior

捷径行为

They, anyand all, both look for a condition that allows them to stop evaluating. The first examples I gave required them to evaluate the boolean for each element in the entire list.

他们,anyall,都在寻找一个允许他们停止评估的条件。我给出的第一个例子要求他们评估整个列表中每个元素的布尔值。

(Note that list literal is not itselflazily evaluated - you could get that with an Iterator- but this is just for illustrative purposes.)

(请注意,列表文字本身并不是惰性求值的 - 您可以使用Iterator获得它- 但这仅用于说明目的。)

Here's a Python implementation of any and all:

这是 any 和 all 的 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!

Of course, the real implementations are written in C and are much more performant, but you could substitute the above and get the same results for the code in this (or any other) answer.

当然,真正的实现是用 C 编写的并且性能更高,但是您可以替换上面的代码并获得与此(或任何其他)答案中的代码相同的结果。

all

all

allchecks for elements to be False(so it can return False), then it returns Trueif none of them were False.

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

The way anyworks is that it checks for elements to be True(so it can return True), then it returnsFalseif none of them wereTrue`.

有效的方法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!

I think if you keep in mind the short-cutting behavior, you will intuitively understand how they work without having to reference a Truth Table.

我认为,如果您牢记捷径行为,您将直观地了解它们的工作原理,而无需参考真值表。

Evidence of alland anyshortcutting:

证据allany捷径:

First, create a noisy_iterator:

首先,创建一个noise_iterator:

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

and now let's just iterate over the lists noisily, using our examples:

现在让我们使用我们的示例来嘈杂地迭代列表:

>>> 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

We can see allstops on the first False boolean check.

我们可以看到all第一个 False 布尔检查的停止。

And anystops on the first True boolean check:

any在第一次 True 布尔检查时停止:

>>> 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

The source

来源

Let's look at the source to confirm the above.

让我们看一下来源以确认上述内容。

Here's the source for any:

这是来源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;
}

And here's the source for all:

这是来源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;
}

回答by Jobin

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

回答by David Gladson

s = "eFdss"
s = list(s)
all(i.islower() for i in s )   # FALSE
any(i.islower() for i in s )   # TRUE

回答by Arthur Tacca

I know this is old, but I thought it might be helpful to show what these functions look like in code. This really illustrates the logic, better than text or a table IMO. In reality they are implemented in C rather than pure Python, but these are equivalent.

我知道这是旧的,但我认为在代码中展示这些函数的样子可能会有所帮助。这确实说明了逻辑,比文本或表格 IMO 更好。实际上,它们是用 C 而不是纯 Python 实现的,但它们是等效的。

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

In particular, you can see that the result for empty iterables is just the natural result, not a special case. You can also see the short-circuiting behaviour; it would actually be more work for there notto be short-circuiting.

特别是,您可以看到空迭代的结果只是自然结果,而不是特殊情况。您还可以看到短路行为;如果没有短路,实际上会做更多的工作。

When Guido van Rossum (the creator of Python) first proposed adding any()and all(), he explained them by just posting exactly the above snippets of code.

当 Guido van Rossum(Python 的创造者)第一次提议添加any()和 时all(),他通过准确地发布上述代码片段来解释它们。

回答by DK250

The concept is simple:

这个概念很简单:

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 

回答by Ajmal Aamir

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 .