为什么“any”和“all”在这里似乎没有使用短路求值?

sta*_*tam 5 python

all()在序列中找到 False 后是否立即返回 False?
尝试运行这段代码:

def return_true():
    print('I have just been printed')
    return True

print(all((False, return_true())))
Run Code Online (Sandbox Code Playgroud)

如您所见,I have just been printed即使前面有 False,也会打印出来。

另一个例子:

def return_false():
    print('I have just been printed')
    return False

print(any((True, return_false())))
Run Code Online (Sandbox Code Playgroud)

在这种情况下,I have just been printed即使之前有 True,也会在此代码中打印。

Joh*_*ica 8

是的,all()两者any()都按照您所描述的方式短路。all()如果任何项目为 false-y,则将提前返回;any()如果任何项目为 true,则将提前返回。

您看到打印输出的原因是因为return_true()return_false()之前被调用过allany甚至被调用过。他们一定是。毕竟,必须在调用函数之前评估函数的参数。

这:

print(all((False, return_true())))
Run Code Online (Sandbox Code Playgroud)

相当于:

x = return_true()
print(all((False, x)))
Run Code Online (Sandbox Code Playgroud)

IEreturn_true()是无条件评估的。

为了获得所需的短路行为,需要延迟评估序列本身。一种简单的方法是创建一个可迭代的对象,不是我们想要测试的值,而是我们可以调用来获取这些值的东西;然后使用生成器表达式创建一个延迟调用它们的序列。也可以看看

在这里,可能看起来像:

print(all(
    x()
    for x in (lambda: False, return_true)
))

print(any(
    x()
    for x in (lambda: True, return_false)
))
Run Code Online (Sandbox Code Playgroud)