为什么Python的“任何”返回一个布尔而不是价值?

andor返回他们评估的最后一个元素,但为什么不是Python的内置函数呢?

我的意思是这样很容易实现自己,但我仍然想知道为什么。

 def any(l): for x in l: if x: return x return x 

编辑:

为了增加下面的答案,这里有一个来自你们这个问题的强大的皇帝相同的邮件列表的实际报价:

是否总是返回True和False或第一个触发/传入元素? 在博客之前我也玩过这个游戏,并且意识到最终的情况(如果顺序是空的,或者所有的元素都不能通过testing)永远不会令人满意:如果参数是一个可重用的布尔值,如果参数是非bool对象的迭代,那么selectFalse会感到奇怪。

Guido van Rossum(主页: http : //www.python.org/~guido/ )

2005年,Python开发人员的邮件列表出现了这个问题,当时Guido Van Rossum提议在Python 2.5中增加all

比尔·詹森要求将它们作为

 def any(S): for x in S: if x: return x return S[-1] def all(S): for x in S: if not x: return x return S[-1] 

执行anyall雷蒙德·赫廷格(Raymond Hettinger)专门回答了为什么any人和all都不像andor

随着时间的推移,我得到了关于这些和其他itertools食谱的反馈。 没有人反对在这些食谱或Guido的版本中的真/假返回值。

Guido的版本匹配任何/所有谓词的正常期望。 此外,它避免了人们目前对Python和“或”的独特实现所遇到的错误/困惑。

回到最后的元素不是邪恶的; 这只是奇怪的,意外的和不明显的。 抵制这一个棘手的冲动。

邮件列表在很大程度上是同意的,如今你所看到的一样。

andor可以明智地定义,他们总是返回他们的操作数之一。 然而, anyall都不能总是被定义为从input序列中返回一个值:特别是当列表为空时,他们不能这样做。 anyall目前都有一个定义良好的结果在这种情况下: any返回False和all返回True。 你将被迫有时返回一个布尔值, 有时从序列中返回一个项目,这使得一个令人不快的和令人惊讶的界面。 更简单和一致。

我对python-ideas问了同样的问题,并被告知原因是any()all()需要在序列为空时返回一个值,这些值必须是FalseTrue 。 这对我来说似乎是一个弱项。

这些函数现在不能改变,但是我认为如果它们返回了他们遇到的第一个正确的或者错误的值,那么它们会更有用,并且更好地模拟and和操作符。

and和的行为or因历史原因而存在。

在Python有一个三元操作/条件expression式之前,你使用andor如果你想在一个条件上使用一个值。 任何这样的expression式都可以用条件expression式语法重写:

 true_val if condition else false_val 

实质上,它们被重载了两个函数,出于兼容性原因,它们没有被改变。

不是超载其他操作的原因。 any似乎它应该告诉你是否条件是真的任何项目 ,这是一个布尔值,所以它应该返回一个bool

any价值都可能是假的,或者是投入中的一个价值,这并不是显而易见的。 另外,大多数用途看起来像

 tmp = any(iterable) if tmp: tmp.doSomething() else: raise ValueError('Did not find anything') 

这是看你跳跃 ,因此unpythonic。 相比于:

 next(i for i in iterable if i).doSomething() # raises StopIteration if no value is true 

andor的行为作为当时不可用的条件expression式的插入,在历史上是有用的。

Any返回一个布尔值,因为它有效地把它的参数作为一个布尔的列表,然后再考虑它们是否为真。 它正在返回它评估的元素,但这恰好是一个布尔值。

你什么时候想使用你的版本? 如果它在bools列表中,那么你已经有了正确的答案。 否则,你只是在防范None ,可能表示为:

 filter(lambda x: x != None, l)[0] 

要么:

 [x for x in l if x != None][0] 

这是一个更明确的意图声明。