[英]Need help understanding Booleans?
我在书中读到有关布尔值的内容,它说:
x和y ------------如果x为假,则返回x。 否则,返回y。
x或y --------------如果x为true,则返回x。 否则,返回y。
从我对“ or”和“ and”的日常使用来看,这对我来说没有意义,如果它说:
x和y ------------如果x为假,则不执行任何操作。 如果y为假,则不执行任何操作。 如果x和y为true,则返回x和y
x或y --------------如果x为true,则返回x。 如果x为假,请检查y。 如果y为假,则不执行任何操作。 如果y为true,则返回y
我是否只需要盲目接受实际定义,还是可以理解它们,因为它们确实有意义。
“什么也不做”是不可行的。 数学表达式x or y
必须具有一个值(如果x
, y
或两者均为true,则为true)。 并且x and y
必须具有一个值(当且仅当x
和y
都为true时才为真)。
您的书定义它们的方式在数学上是正确的,但会造成混淆(直到您陷入短路评估之类的问题)。
与某些其他语言不同,可以将任何对象用作布尔运算的操作数。 您所有的书都说,您可以将布尔运算符用作值的快速“过滤器”。
例如,假设您要在两个列表之间选择一个非空列表。 以下是一种有效的方法(以及更多的Pythonic方法):
>>> [] or ['something', 'here']
['something', 'here']
对比(不使用Python中的Python惯用法):
if len(l1) != 0:
return l1
else:
return l2
您的书是正确的-请参阅文档 。 乍一看可能并不直观,但是这种行为(称为短路 )非常有用。 在简单的情况下,它可以使您在检查某些条件时节省大量时间。 在此示例中,函数f
花费10秒进行评估,您肯定可以看到一种用法:
if f(foo) or f(bar) or f(baz):
如果f(foo)
为True
,则无需评估f(bar)
或f(baz)
,因为整个if语句为True
。 这些值是不必要的,您只会浪费时间计算它们。
此行为的另一个极为常见的用法是在null(或对于python None
)检查中。 它允许在一行内安全使用所有功能:
if obj != None and obj.foo():
如果obj
为None
,则if语句保证为False
,因此无需检查(甚至评估) obj.foo()
,这很好,因为这会导致异常。
短路在许多编程语言中都很常见,一旦您完全了解如何使用它,它就会非常有用。
虽然这本书以一种有点混乱的方式介绍了它,但这是正确的。 布尔逻辑必须为true或false。
为了使X和Y都返回true,它们都必须为true,如果X为false,则返回false。 如果X为true,则返回Y,Y为true或false以及正确答案。
为了使X或Y返回false,它们都必须为false。 如果X为true,则可以返回true(X)。 如果X为假,则返回Y的值。
包括Python在内的许多(大多数?)编程语言都使用其布尔运算符and
和or
实现短路 。 因此,他们从左到右评估操作数,并在确定最终结果后立即停止。
由于x and y and z and ...
在任何操作数为假的情况下都保证为假,因此一旦遇到错误,它将立即停止对操作数的求值。 并且x or y or z or ...
在任何操作数为true的情况下都保证为true,因此一旦到达真实操作数,它就会停止。 无论哪种情况,如果它们一直到达最后一个操作数,则它们将返回其值。
在某些语言中,布尔运算符只返回严格的布尔结果,即true
或false
(在某些语言中,它们表示为1
和0
)。 但是在Python(以及其他一些语言,例如Javascript和Common Lisp)中,它们返回最后一个被求值的操作数的值,该值确定了最终结果。 这通常比仅表达真值更有用。
当您将这些功能放在一起时,它允许一些简洁的习惯用法,例如
quotient = b != 0 && a/b
代替
if b != 0:
quotient = false
else:
quotient = a/b
该行为可能看起来很奇怪,但是请考虑以下假设示例。 从显而易见的事情开始
>>> True and False
False
>>> False and True
False
这很容易理解,因为我们正在处理布尔值。 记住这个例子,因为其他每个例子都可以这样思考。
现在考虑在比较之前, and
和or
运算符是否将每个对象都转换为布尔值。 例如,空字符串或空列表将为False
,非空字符串或将为True
。 看起来像这样( 显然这不是实际的样子 )
>>> "vanilla" and ""
False
>>> "" and "vanilla"
False
这是很合理的。 毕竟bool("vanilla") and bool("")
会与True and False
相同,我们已经知道它是False
不过,它可以进行比较而无需将其实际转换为True
或False
,而无需进行转换 。 结果,您实际上并不需要它返回True
或False
。 它可以只返回它测试的实际对象。
>>> "vanilla" and ""
""
>>> "" and "vanilla"
""
出于真理测试的目的,返回""
与返回False
相同,因此无需将其转换为布尔值。 这就是为什么它总是返回其真值与运算符的结果相同的对象的原因。
第一组描述是快捷方式:跟随这些快捷方式将为您提供与true和false的“常规定义”完全相同的结果。
但是您自己的描述没有多大意义。 你不能“什么都不做”。 您必须从比较中返回一些值,即true或false。 而且,您也不能返回a和b:再次,布尔比较的结果必须是布尔,而不是一对布尔。
如果在每种情况下考虑一下,可能会更容易
x和y ------------如果x为假,则返回x。 否则,返回y。
x或y --------------如果x为true,则返回x。 否则,返回y。
情况1:x = true,y = true
“如果x为假,则返回x。否则,返回y。”
然后,将返回y,这是正确的。 这是有道理的,因为x和y都为真。
(true和true == true)
“如果x为true,则返回x。否则,返回y。”
这将返回x,这是正确的。 这是有道理的,因为x或y中的一个为真。
(正确或正确== true)
案例2:x =否,y =正确
“如果x为假,则返回x。否则,返回y。”
然后,它将返回x,这是错误的。 这是有道理的,因为x和y都不是真的。
(错误和正确==否)
“如果x为true,则返回x。否则,返回y。” 这将返回y。 这是有道理的,因为x或y中的一个为真。
(false或true == true)
情况3:x = true,y = false
“如果x为假,则返回x。否则,返回y。”
然后将返回y,它是错误的。 这是有道理的,因为x和y都不是真的。
(是非==假)
“如果x为true,则返回x。否则,返回y。”
然后这将返回x,这是正确的。 这是有道理的,因为x或y为真
(对或错== true)
情况4:x =否,y =否
“如果x为假,则返回x。否则,返回y。”
然后,它将返回x,这是错误的。 这是有道理的,因为x和y都不是真的。
(错误和错误==错误)
“如果x为true,则返回x。否则,返回y。”
这将返回y,它是错误的。 这是有道理的,因为x和y都不为真。
(错误或错误==错误)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.