【问题标题】:Need help understanding Booleans?需要帮助理解布尔值?
【发布时间】:2015-07-14 21:01:20
【问题描述】:

我正在阅读我书中的布尔值,它说:

x 和 y------------如果 x 为假,则返回 x。否则,返回 y。

x 或 y-------------如果 x 为真,则返回 x。否则,返回 y。

从“or”和“and”的日常用法来看,这对我来说没有意义 对我来说,如果它说:

x 和 y------------如果 x 为假,什么也不做。如果 y 为假,则什么也不做。如果 x 和 y 为真,则返回 x 和 y

x 或 y-------------如果 x 为真,则返回 x。如果 x 为假,请检查 y。如果 y 为假,则什么也不做。如果 y 为真,则返回 y

我只是需要盲目地接受实际的定义,还是我可以理解它们,因为它们确实有意义。

【问题讨论】:

  • @ben_frankly 标题是 John Zelle 的“Python 编程:计算机科学导论”第 2 版。我所说的图表在第 257 页
  • 如何使用and 实现或定义and
  • 这本书完全正确。看看x and y 如何使用失败事物的虚假值,而不是NoneFalse 硬编码。例如,False and 13 将评估为False,而None and 13 将评估为None

标签: python python-3.x boolean


【解决方案1】:

“什么都不做”不是一个选项。数学表达式x or y 必须 有一个值(如果xy 或两者都为真,则为真)。并且x and y 必须有一个值(当且仅当xy 都为真时才为真)。

你的书定义它们的方式在数学上是正确的,但令人困惑(直到你进入短路评估之类的东西)。

【讨论】:

  • 这在本书开始使用实际字符串之前是有意义的。有一个代码 flavor = input("What flavor do you want [vanilla]: ") 或 "vanilla" 。当您输入一个空字符串时,为什么它返回字符串“vanilla”而不是单词“True”,因为“vanilla”是一个非空字符串,其计算结果为true?
  • 是的,Python 试图比简单的布尔值更高级一些。如果您输入了某些内容,则该字符串将为真,Python 可以将其作为表达式的结果返回。但是一个空字符串是假的,所以它评估第二个参数(“vanilla”)是真的,并返回它。这是一个 Python 的怪癖——不要指望学习这个对一般编程或现实生活有任何价值。
【解决方案2】:

这种行为可能看起来很奇怪,但请考虑以下假设示例。从显而易见的事情开始,

>>> True and False
False
>>> False and True
False

这很容易理解,因为我们处理的是布尔值。记住这个例子,因为其他所有例子都可以这样理解。

现在考虑andor 运算符是否在比较之前将每个对象转换为布尔值。例如,空字符串或空列表为False,非空字符串为True。它看起来像这样(显然这不是它实际的样子

>>> "vanilla" and ""
False
>>> "" and "vanilla"
False

这很有意义。毕竟bool("vanilla") and bool("")True and False 相同,我们已经知道是False

不过,它可以进行比较without ever converting them,而不是将它们实际转换为TrueFalse。因此,您实际上并不需要它返回 TrueFalse。它可以只返回它测试的实际对象。

>>> "vanilla" and ""
""
>>> "" and "vanilla"
""

出于测试目的,返回"" 与返回False 相同,因此无需将其转换为布尔值。这就是为什么它总是返回一个真值与运算符结果相同的对象。

【讨论】:

    【解决方案3】:

    与其他一些语言不同,您可以使用any object 作为布尔运算的操作数。你所有的书都说你可以使用布尔运算符作为值的快速“过滤器”。

    例如,假设您想在两个列表之间选择一个非空列表。以下是一种有效的(并且更 Pythonic)的方法:

    >>> [] or ['something', 'here']
    ['something', 'here']
    

    对比(不使用 Python 中的 Python 习语):

    if len(l1) != 0:
      return l1
    else:
      return l2
    

    【讨论】:

      【解决方案4】:

      你的书是对的 - 请参阅documentation。一开始可能不直观,但这种行为(称为short-circuiting)非常有用。在一个简单的情况下,它可以让您在检查某些条件时节省大量时间。在这个例子中,函数 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():
      

      如果objNone,则if语句保证为False,因此无需检查(甚至评估)obj.foo(),这很好,因为这会导致异常.

      短路在许多编程语言中很常见,一旦你完全了解了如何使用它就会非常有用。

      【讨论】:

        【解决方案5】:

        虽然这本书以一种稍微令人困惑的方式呈现它,但它是正确的。布尔逻辑必须评估为真或假。

        对于 X 和 Y 要返回 true,它们都必须为 true,如果 X 为 false,则返回 false。如果 X 为真,则返回 Y,它是真或假,也是正确答案。

        要使 X 或 Y 返回 false,它们都必须为 false。如果 X 为真,则它可以返回真 (X)。如果 X 为假,则返回 Y 的值。

        【讨论】:

          【解决方案6】:

          许多(大多数?)编程语言,包括 Python,在其布尔运算符 andor 中实现 short-circuiting。所以他们从左到右评估他们的操作数,并在最终结果确定后立即停止。

          由于x and y and z and ... 在任何操作数为假时保证为假,因此一旦遇到假操作数,它就会停止计算操作数。如果任何操作数为真,则x or y or z or ... 保证为真,因此它一到达真操作数就停止。在任何一种情况下,如果它们一直到最后一个操作数,它们就会返回它的值。

          在某些语言中,布尔运算符只返回严格的布尔结果,truefalse(在某些语言中,这些表示为 10)。但是在 Python(以及其他一些,例如 Javascript 和 Common Lisp)中,它们返回最后一个被评估的操作数的值,这决定了最终的结果。这通常比表达式的真值更有用。

          当你把这些特性放在一起时,它允许一些简洁的习语,例如

          quotient = b != 0 && a/b
          

          而不是

          if b != 0:
              quotient = false
          else:
              quotient = a/b
          

          【讨论】:

            【解决方案7】:

            第一组描述是捷径:遵循这些将给出与真假的“通常定义”完全相同的结果。

            但是您自己的描述没有多大意义。你不能“什么都不做”;您必须从比较中返回一些值,无论是真还是假。而且你不能同时返回 a 和 b:同样,布尔比较的结果必须是一个布尔值,而不是一对布尔值。

            【讨论】:

            • “真或假”——不能保证这些操作的值是真还是假;换一种说法可能会更好。
            【解决方案8】:

            如果你在每个字面情况下考虑它可能会更容易

            x 和 y------------如果 x 为假,则返回 x。否则,返回 y。

            x 或 y-------------如果 x 为真,则返回 x。否则,返回 y。


            案例 1:x = true,y = true

            "如果 x 为假,则返回 x。否则,返回 y。"

            然后这将返回 y ,这是真的。这是有道理的,因为 x 和 y 都是真的。

            (真与真 == 真)

            "如果 x 为真,则返回 x。否则,返回 y。"

            this 将返回 x ,这是真的。这是有道理的,因为 x 或 y 之一为真。

            (真或真 == 真)


            案例 2:x = 假,y = 真

            "如果 x 为假,则返回 x。否则,返回 y。"

            然后这将返回 x 是假的。这是有道理的,因为 x 和 y 并不都是真的。

            (假和真 == 假)

            "如果 x 为真,则返回 x。否则,返回 y。" 这将返回 y。这是有道理的,因为 x 或 y 之一为真。

            (假或真 == 真)


            案例 3:x = 真,y = 假

            "如果 x 为假,则返回 x。否则,返回 y。"

            然后这将返回 y,它是 false。这是有道理的,因为 x 和 y 并不都是真的。

            (真假==假)

            "如果 x 为真,则返回 x。否则,返回 y。"

            然后这将返回 x 这是真的。这是有道理的,因为 x 或 y 为真

            (真或假 == 真)


            案例 4:x = 假,y = 假

            "如果 x 为假,则返回 x。否则,返回 y。"

            然后这将返回 x 是假的。这是有道理的,因为 x 和 y 并不都是真的。

            (假和假==假)

            "如果 x 为真,则返回 x。否则,返回 y。"

            this 将返回 y,它是 false。这是有道理的,因为 x 和 y 都不是真的。

            (假或假==假)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-06-04
              • 2017-04-04
              • 2013-04-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-04-26
              相关资源
              最近更新 更多