为什么蟒蛇`any`返回一个布尔值,而不是价值?(Why does python `any` ret

2019-06-23 16:24发布

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

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

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

编辑:

要添加到下面的答案,这里是从你们强大的皇帝在这个问题上的相同的邮件列表中的实际报价:

是否总是返回True和False或第一faling /通过元件? 我打了,太多博客之前,并意识到结束的情况下(如果该序列为空或所有元素测试失败)永远不能做出令人满意的工作:挑选无如果参数是布尔变量的迭代感觉怪怪的,和如果参数不为布尔对象的迭代采摘虚假感觉怪怪的。

吉多·范罗苏姆(主页: http://www.python.org/~guido/ )

Answer 1:

就此问题在2005年走到了Python开发的邮件列表上,当吉多·范罗苏姆建议增加anyall到Python 2.5。

比尔·詹森要求 ,他们将作为实施

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 , 回应专门针对为什么anyall并不表现的像andor

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

圭多的版本相匹配的任何正常期望/全部为谓语。 此外,它避免了样的错误/混乱,人们目前与Python的唯一实现的“与”和“或”体验。

返回的最后一个元素是不是邪恶的; 它只是奇怪的,意外的和非显而易见的。 抵制的呼吁得到棘手的这一个。

邮件列表很大程度上同意,离开执行,你今天看到它。



Answer 2:

andor可在某种程度上理智地定义他们总是返回他们的一个操作数。 然而, anyall不理智总是定义为从它们的输入顺序返回值:明确他们不能这样做,当列表为空。 无论anyall目前在这种情况下,一个明确的结果: any返回false, all返回TRUE。 你将被迫有时返回一个布尔值, 有时从序列,这使得不愉快和令人惊讶的接口返回一个项目。 更好的是简单和一致。



Answer 3:

我问这个同样的问题在蟒蛇的思路 ,被告知的原因是any()all()需要时序列为空返回一个值,这些值必须是FalseTrue 。 这似乎是一个薄弱的论据给我。

该功能现在已无法改变,但我认为他们会更加有用,并且更好的类似物andor运营商,他们一概而论,如果他们返回的第一个真正的十岁上下或假十岁上下的价值就遇到了。



Answer 4:

的行为andor存在历史原因。

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

true_val if condition else false_val

从本质上讲,它们是重载有两个功能,并且为了兼容性的原因,他们并没有被改变。

这是不是一个理由超载等操作。 any看起来像它应该告诉你一个条件是否为任何项目 ,这是一个布尔值true,所以它应该返回一个bool



Answer 5:

这不是明显,在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是作为一个下拉为当时不可用的条件式历史是有用的。



Answer 6:

Any因为它有效地将它的参数作为布尔变量的考虑,如果其中任何一个为真,前一个列表返回一个布尔值。 返回它计算元素,但是这恰好是一个布尔值。

你什么时候想用你的版本, any ? 如果它的bool的列表上,则你已经拥有了正确的答案。 否则,你只是防范None ,可能被表示为:

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

要么:

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

这是意图有更明确的说法。



Answer 7:

开始Python 3.8 ,并引入的赋值表达式(PEP 572) ( :=操作者),我们可以可替换地明确地捕捉的证人 any表达或的 all表达式:


引述的几个例子PEP描述 :

if any(len(long_line := line) >= 100 for line in lines):
  print("Extremely long line:", long_line)
if all((nonblank := line).strip() == '' for line in lines):
  print("All lines are blank")
else:
  print("First non-blank line:", nonblank)


文章来源: Why does python `any` return a bool instead of the value?