Python的所有函数如何工作?

问题:Python的所有函数如何工作?

我想明白是怎么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?

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

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

d is a 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.

Why is it evaluating to False for all tuples?


回答 0

你可以粗略地认为anyall作为系列的逻辑orand分别运营。

任何

anyTrue至少一个元素是Truthy 时将返回。阅读有关真值测试的信息。

所有

allTrue仅在所有元素都将返回时都是真。

真相表

+-----------------------------------------+---------+---------+
|                                         |   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如果iterable的任何元素为true,则返回。如果iterable为空,则返回False

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

all

返回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))是一个生成器表达式,True如果1和9中的当前数字是6的倍数,则返回。anymultiples_of_6it进行迭代,并在满足6时找到True值,因此它立即返回True,其余的multiples_of_6不进行迭代。那就是我们打印时看到的list(multiples_of_6)的结果78并且9

这个聪明的东西在 这个答案中


有了基本的了解,如果我们看一下您的代码,您就会

any(x) and not all(x)

这可以确保至少其中一个值是Truthy,但不是全部。这就是为什么它回来了[False, False, False]。如果您真的想检查两个数字是否不相同,

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

You can roughly think of any and all as series of logical or and and operators, respectively.

any

any will return True when at least one of the elements is Truthy. Read about Truth Value Testing.

all

all will return True only when all the elements are 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

any

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

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

all

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

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


Note 2:

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

>>> 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 True if the current number within 1 and 9 is a multiple of 6. any iterates the multiples_of_6 and when it meets 6, it finds a Truthy value, so it immediately returns True, and rest of the multiples_of_6 is not iterated. That is what we see when we print list(multiples_of_6), the result of 7, 8 and 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,

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

回答 1

Python anyall函数如何工作?

anyall获取iterables并返回(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

如果iterables为空,则any返回False,然后all返回True

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

我当时正在向学生演示all和演示any。他们大多对空可迭代对象的返回值感到困惑。用这种方式进行解释导致许多灯泡打开。

捷径行为

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

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

这是所有内容的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!

我认为,如果您牢记捷径,您将直观地了解它们的工作方式,而不必引用真值表。

all和的证据any捷径:

首先,创建一个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停止执行第一个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

来源

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

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

How do Python’s any and all functions work?

any and all take iterables and return True if any and all (respectively) of the elements are 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

If the iterables are empty, any returns False, and all returns True.

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

I was demonstrating all and any for 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.

Shortcutting behavior

They, any and 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.

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

Here’s a Python implementation of any and all:

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.

all

all checks for elements to be False (so it can return False), then it returns True if none of them were 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

The way any works is that it checks for elements to be True (so it can return True), then it returnsFalseif 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 all and any shortcutting:

First, create a noisy_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 all stops on the first False boolean check.

And any stops on the first True boolean check:

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

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:

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

回答 2

我知道这很旧,但是我认为在代码中显示这些功能看起来会有所帮助。这确实说明了逻辑,比文本或表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

特别是,您可以看到空可迭代对象的结果只是自然结果,而不是特殊情况。您还可以看到捷径。它实际上将是更多的工作有没有被短路。

当Guido van Rossum(Python的创建者)首次提出添加any()and时all(),他只是通过准确地发布上述代码片段来解释它们。

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.

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 not to 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.


回答 3

您要查询的代码来自此处给出的答案。目的是解决比较多个位数组(即1和的集合)的问题0

anyall当您可以依赖值的“真实性”(即布尔值上下文中的值)时,此选项很有用。1是True,0是False,答案利用了一个便利。5也恰好是True,因此当您将其混入可能的输入中时…好。不起作用

您可以改为执行以下操作:

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

它缺乏先前答案的美感(我真的很喜欢的外观any(x) and not all(x)),但是可以完成工作。

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 1 and 0.

any and all are useful when you can rely on the “truthiness” of values – i.e. their value in a boolean context. 1 is True and 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.

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 really liked the look of any(x) and not all(x)), but it gets the job done.


回答 4

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

回答 5

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

回答 6

这个概念很简单:

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 

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 

回答 7

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