【问题标题】:How is this conditional being handled?如何处理这个条件?
【发布时间】:2017-01-05 03:27:53
【问题描述】:

我刚刚在我的代码中遇到了一个奇怪的错误,因为我在条件中使用了逗号而不是 and 关键字。请参阅下面的代码以获取简化的示例:

def foo():
    s = set([1, 2, 3])
    a = 4
    b = 5
    if (a, b in s):      # Should have been: if (a and b in s):
        print "Foo"

foo()  # prints "Foo"

为什么条件计算结果为True?即使aNone,也会打印“Foo”。

【问题讨论】:

  • 我想你已经创建了一个元组。它由ab in s 的结果组成,您正在测试元组的真实性。

标签: python


【解决方案1】:

表达式 (a, b in s) 是一个有效的 Python 元组。无论其内容如何,​​只要它至少具有一个元素,它将评估为 Truth。 (这个有两个)。

【讨论】:

  • 感谢您的解释-当我刚刚评估 (a, b in s) 并返回一个元组时,我应该发布这个。事后明显!一旦 10 分钟计时器用完,我会接受这个答案。
【解决方案2】:

这是因为(a, b in s) 的计算结果为长度为 2 的元组 (4, False),而在 python 中,如果元组的长度不为零,则将其视为 True

【讨论】:

    【解决方案3】:

    代码打印 'Foo' 而不管 a 的值和 b 是否在 s 中的原因是这一行:

    (a, b in s)

    实际上是一个元组。 if 语句检查元组是否存在,并且它会打印 Foo。 当

    s=set([1,2,3])
    a=None
    b=5
    

    检查的条件是

    if(None, False):
    

    这总是正确的,因为

    (None, False) #is a non empty tuple.
    

    【讨论】:

    • (写成“元组”,而不是“元组”)
    • @jsbueno 谢谢
    【解决方案4】:

    正如其他人所说,表达式a, b in s 创建一个元组,一个非空元组是真实的,即它在布尔上下文中计算为True。请注意,逗号创建的是元组,而不是括号,尽管在某些情况下需要括号以避免歧义,例如将元组文字作为单个函数参数传递时。

    顺便说一句,Python 中 if 语句的条件表达式不需要括号。它们不会受到伤害,但通常的样式约定是将它们作为不必要的杂乱而省略。

    请注意,if a and b in s: 确实测试ab 是否都是集合s 的元素。要执行该测试,您应该使用set.issuperset 方法:

    if s.issuperset((a, b)):
    

    请注意,这里需要额外的括号,因为我们将元组 a, b 作为单个参数传递。

    该语句也可以使用.issuperset的运算符形式编写:

    if s >= set((a, b)):
    

    但是当使用这种形式时,两个操作数都必须是集合(或frozensets),而完整方法将接受任何可迭代作为其他参数。

    但是回到你的代码......表达式

    a and b in s
    

    等价于

    a and (b in s) 
    

    如果a 是假的(即False、0 或空集合),则表达式的计算结果为a,并且and 表达式的第二部分被忽略。否则(当a 是真值时)and 表达式的第二部分被评估并成为结果。

    换句话说,如果a == 0a and b in s 的结果为0,但如果a 是任何其他数字,则a and b in s 将导致True 如果bs 中,并且它如果b 不在s 中,将导致False。请参阅我对Assigning string with boolean expression 的回复以获取更多信息(附有大量示例)。

    【讨论】:

      猜你喜欢
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 2014-12-26
      • 2015-04-16
      • 2019-03-16
      • 2011-12-13
      相关资源
      最近更新 更多