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
How do Python's any and all functions work?
提问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 True
and 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]?
d
is 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 any
and all
as series of logical or
and and
operators, respectively.
您可以粗略地将any
和 分别all
视为一系列逻辑or
和and
运算符。
any
任何
any
will return True
when at least one of the elementsis Truthy. Read about Truth Value Testing.
any
True
当至少一个元素为Truthy时将返回。阅读真值测试。
all
全部
all
will return True
only when all the elementsare Truthy.
all
True
只有当所有元素都为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在官方文档中有说明,像这样
Return
True
if any element of the iterable is true. If the iterable is empty, returnFalse
True
如果迭代的任何元素为真,则返回。如果可迭代对象为空,则返回False
Since none of the elements are true, it returns False
in this case.
由于所有元素都不为真,因此False
在这种情况下返回。
Return
True
if all elements of the iterable are true (or if the iterable is empty).
返回
True
如果迭代的所有元素都是真(或者,如果可迭代为空)。
Since none of the elements are false, it returns True
in this case.
由于没有一个元素是假的,它True
在这种情况下返回。
Note 2:
笔记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,
另一个重要的事情了解any
和all
,它会短路的执行,他们知道结果的那一刻。优点是,不需要消耗整个迭代。例如,
>>> 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
.
这里,(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)
的7
,8
和的结果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 1
and 0
.
你问的有问题的代码来自我在这里给出的答案。它旨在解决比较多个位数组的问题 - 即1
和 的集合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.
any
并且all
当您可以依赖值的“真实性”时很有用 - 即它们在布尔上下文中的值。1 是True
0 是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
any
andall
functions work?
Python
any
和all
函数是如何工作的?
any
and all
take iterables and return True
if any and all (respectively) of the elements are True
.
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
If the iterables are empty, any
returns False
, and all
returns True
.
如果可迭代对象为空,则any
返回False
,并all
返回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.
我演示all
并any
为今天学生上课。他们大多对空迭代的返回值感到困惑。以这种方式解释它会导致许多灯泡亮起。
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.
他们,any
和all
,都在寻找一个允许他们停止评估的条件。我给出的第一个例子要求他们评估整个列表中每个元素的布尔值。
(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
all
checks for elements to be False
(so it can return False
), then it returns True
if 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 any
works is that it checks for elements to be True
(so it can return True), then it returns
Falseif none of them were
True`.
有效的方法any
是检查元素是否存在True
(因此它可以返回True), then it returns
False if none of them were
True`。
>>> 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:
证据all
和any
捷径:
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 all
stops on the first False boolean check.
我们可以看到all
第一个 False 布尔检查的停止。
And any
stops 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 .