Python:如何将布尔测试链接到第一个False后立即获取False

时间:2012-04-27 18:35:50

标签: python boolean short-circuiting truthtable

在尝试减少嵌套ifs(以及停止工作的脚本)之后遇到了很多麻烦,我意识到我对错误的概念是错误的想法以及boolean stuff在python中是如何工作的。

我有这个(工作正常但扭曲):

if (not gotside):
    if (j > 1):
        if (j < a.shape[1] - 1):
            if a[i, j+unit]:
                print "only now I do stuff!"

尝试了这一点(看起来因为没有按照预期工作而感到惊讶):

if (not gotside) and (j > 1) and (j < a.shape[1] - 1) and a[i, j+unit]:
    print "I'm well tested but not so indented..."

然后我尝试使用“或”代替“和”,但没有用,因为(后来我发现)当你使用x and y甚至x or y时,你得到{{1}之一根据文档,而不是x, y之一。

所以,我不知道如何一个接一个地放置一些测试(最好是在同一行中,使用布尔运算符),使整个表达式在第一个表达式返回True, False时test评估为False。

感谢阅读!

5 个答案:

答案 0 :(得分:6)

你的例子应该有用。

if x and y and z:
    ...

只有当x,y和z都没有计算到False,并且在Python中and短路时才会发生,所以只要一个项目返回False值就会发生失败。我们可以很容易地证明这一点:

>>> def test(n):
...     print("test", n)
...     return n
... 
>>> test(1) and test(2)
test 1
test 2
2
>>> test(0) and test(2)
test 0
0
>>> test(0) and test(2) and test(3)
test 0
0
>>> test(1) and test(0) and test(3)
test 1
test 0
0

答案 1 :(得分:3)

我看到了你的担忧,但请记住,只要Python中的某个if语句中有内容,它就会隐式转换为条件的bool。因此,当3 or 2返回33 and 2单独完成时返回2时,if 3 or 2实际上等同于说if bool(3 or 2),所以你无论布尔逻辑在其他上下文中返回什么,无论布尔逻辑在其他上下文中返回什么,都会得到逻辑在条件中返回时返回的falsey或truey值。

答案 2 :(得分:3)

是的,我必须同意其他人说你的例子应该按照你的意愿行事。你是对的x or y返回x,y中的一个,但该对象将被评估为True或False。这就是python如何评估if语句。它应该按照书面形式工作,因为您的表达式将按顺序进行计算,并且一旦行中的任何测试返回为False(或0,或[]{}等),它将返回False。你可以看到,如果python实际尝试过它会导致错误的测试。

x = 1; y = 2
if x < y and x == y and d['a']: # d doesn't exist
    print 'This will never be printed'

如果您的代码没有按预期运行,请详细说明您的预期,以及实际执行的操作。

答案 3 :(得分:1)

Python(以及大多数其他编程语言)中的布尔和运算符提供“短路”功能。这意味着,如果第一个术语或表达式的评估结果为假,则第二个术语甚至不会被评估:

>>> False and expensiveFunctionReturningBool()
False

永远不会调用昂贵的函数,因为Python解释器会在第一个术语被确定为False后立即将表达式评估为False。这是有效的,因为在布尔逻辑中,如果和表达式的一边是假,则整个表达式根据定义为假

Python也使用短路逻辑或。在这种情况下,如果第一个术语被确定为True,则永远不会评估第二个术语。

>>> True or expensive()
True

因此,布尔表达式可用于折叠嵌套的if语句(前提是它们一个接一个地声明),如果通过记住短路逻辑巧妙地使用它们,它们也可以优化条件表达式。 p>

祝你好运!

答案 4 :(得分:1)

我对你没有包含的代码做了一些假设,并添加它以使程序运行:

gotside = False
j = 2
i = 1
unit = 3

class A:
    def __init__(self):
        self.shape = [1, 4]
    def __getitem__(self, pos):
        return pos

a = A()


if (not gotside):
    if (j > 1):
        if (j < a.shape[1] - 1):
            if a[i, j+unit]:
                print("only now I do stuff!")

if (not gotside) and (j > 1) and (j < a.shape[1] - 1) and a[i, j+unit]:
   print("I'm well tested but not so indented...")

对我来说,这适用于python 2.5,2.6,2.7和3.2:

only now I do stuff!
I'm well tested but not so indented...

如果这对您有用,请检查上述程序吗?如果是这样,您能否提供有关您使用的类的更多信息 - 尤其是变量类a