“全部”的原因是:和“任何”结果为空列表
在 Python 中,内置函数 all
和any
返回 True
和 False
分别表示空迭代。我意识到,如果反过来的话,这个问题仍然可以问。但我想知道为什么选择这种特定行为。它是任意的吗?是否同样容易出现相反的情况,或者是否有根本原因?
(我问的原因很简单,因为我从来不记得哪个是哪个,如果我知道其背后的基本原理,那么我可能会知道。还有,好奇心。)
In Python, the built-in functions all
and any
return True
and False
respectively for empty iterables. I realise that if it were the other way around, this question could still be asked. But I'd like to know why that specific behaviour was chosen. Was it arbitrary, ie. could it just as easily have been the other way, or is there an underlying reason?
(The reason I ask is simply because I never remember which is which, and if I knew the rationale behind it then I might. Also, curiosity.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
打个比方怎么样……
你有一个袜子抽屉,但目前是空的。里面有黑袜子吗?不——你根本没有袜子,所以你当然没有黑色的袜子。显然
any([])
必须返回 false - 如果它返回 true 这将是违反直觉的。all([])
的情况稍微困难一些。请参阅关于空洞的真相的维基百科文章。另一个类比:如果一个房间里没有人,那么那个房间里的每个人都会说法语。数学上
all([])
可以写成:关于空洞的陈述是否应该被视为真实存在相当多的争论,但从逻辑的角度来看,它是最有意义的:
还来自文章:
在 Python 中定义一个“空洞为真”的语句返回 false 会违反最小惊讶原则。
How about some analogies...
You have a sock drawer, but it is currently empty. Does it contain any black sock? No - you don't have any socks at all so you certainly don't have a black one. Clearly
any([])
must return false - if it returned true this would be counter-intuitive.The case for
all([])
is slightly more difficult. See the Wikipedia article on vacuous truth. Another analogy: If there are no people in a room then everyone in that room can speak French.Mathematically
all([])
can be written:There is considerable debate about whether vacuous statements should be considered true or not, but from a logical viewpoint it makes the most sense:
Also from the article:
Defining a "vacuously true" statement to return false in Python would violate the principle of least astonishment.
any
的一个属性是它的递归定义,这意味着
当且仅当
any([])
定义为是假的。与全部
类似。One property of
any
is its recursive definitionThat means
The equality is correct for any
x
if and only ifany([])
is defined to be False. Similar forall
.我相信
all([])==True
通常更难掌握,因此这里有一系列示例,我认为这种行为显然是正确的:I believe
all([])==True
is generally harder to grasp, so here are a collection of examples where I think that behaviour is obviously correct:我认为它们是这样实现的,但
不确定它们是这样实现的
I think of them as being implemented this way
not sure they are implemented that way though
Perl 6 还认为空列表上的
all()
和any()
应该作为其各自归约运算符的合理基本情况,因此all ()
为 true,any()
为 false。也就是说
all(a, b, c)
相当于[&] a, b, c
,相当于a & b& c
(减少“连接与”运算符,但您可以忽略连接并将其视为本文的逻辑与),并且any(a, b, c)
相当于[|] a, b, c
,相当于a |乙| c
(减少“连接或”运算符——同样,您可以假装它与逻辑或相同,而不会遗漏任何内容)。任何可以应用归约的运算符在归约 0 项时都需要有一个定义的行为,通常这是通过拥有一个自然的单位元素来完成的——例如,
[+]()
(归约)跨零项的加法)为 0,因为 0 是加法恒等式;向任何表达式添加零都会使其保持不变。[*]()
同样是 1,因为 1 是乘法恒等式。我们已经说过,all
相当于[&]
,any
相当于[|]
-- 好吧,真理是和-恒等式,虚假是或-恒等式-- x 和 True 是 x,并且 >x 或 False 是 x。这使得all()
不可避免地应该为 true,而any()
应该为 false。从一个完全不同(但实用)的角度来看,
any
是一个闩锁,它从 false 开始,只要看到 true 就变为 true;all
是一个锁存器,它从 true 开始,每当看到 false 时就变为 false。不给他们任何参数意味着他们没有机会改变状态,所以你只是问他们的“默认”状态是什么。 :)Perl 6 also takes the position that
all()
andany()
on empty lists should serve as sane base-cases for their respective reduction operators, and thereforeall()
is true andany()
is false.That is to say,
all(a, b, c)
is equivalent to[&] a, b, c
, which is equivalent toa & b & c
(reduction on the "junctive and" operator, but you can ignore junctions and consider it a logical and for this post), andany(a, b, c)
is equivalent to[|] a, b, c
, which is equivalent toa | b | c
(reduction on the "junctive or" operator -- again, you can pretend it's the same as logical or without missing anything).Any operator which can have reduction applied to it needs to have a defined behavior when reducing 0 terms, and usually this is done by having a natural identity element -- for instance,
[+]()
(reduction of addition across zero terms) is 0 because 0 is the additive identity; adding zero to any expression leaves it unchanged.[*]()
is likewise 1 because 1 is the multiplicative identity. We've already said thatall
is equivalent to[&]
andany
is equivalent to[|]
-- well, truth is the and-identity, and falsity is the or-identity -- x and True is x, and x or False is x. This makes it inevitable thatall()
should be true andany()
should be false.To put it in an entirely different (but practical) perspective,
any
is a latch that starts off false and becomes true whenever it sees something true;all
is a latch that starts off true and becomes false whenever it sees something false. Giving them no arguments means giving them no chance to change state, so you're simply asking them what their "default" state is. :)any
和all
在 python 中与其他地方具有相同的含义:any
为 trueall
如果至少有一个不为真则不为真any
andall
have the same meaning in python as everywhere else:any
is true if at least one is trueall
is not true if at least one is not true这实际上更像是一个注释,但是注释中的代码效果不太好。
除了解释
any()
和all()
工作原理的其他逻辑基础之外,它们还必须具有相反的“基本”情况,以便这种关系成立:如果
iterable
的长度为零,则上述内容仍然应该成立。因此,这相当于
如果
any([])
是正确的,那将是非常令人惊讶的。This is really more of a comment, but code in comments doesn't work very well.
In addition to the other logical bases for why
any()
andall()
work as they do, they have to have opposite "base" cases so that this relationship holds true:If
iterable
is zero-length, the above still should hold true. Thereforewhich is equivalent to
And it would be very surprising if
any([])
were the one that is true.官方原因尚不清楚,但从文档来看(确认@John La Rooy 的帖子):
另请参阅 CPython 实现和注释。
The official reason is unclear, but from the docs (confirming @John La Rooy's post):
See also the CPython-implementation and comments.