Python 3和 - 或vs if-else

时间:2014-04-29 13:13:58

标签: python if-statement python-3.x operators logical-operators

以下是否有任何区别?

print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')

4 个答案:

答案 0 :(得分:10)

两行与:

相同
print(x or 'no x available')

关于第二种选择: 请始终牢记,根据运算符优先级and首先进行评估,因此它首先计算x and x,这完全没用 - 它等于x

答案 1 :(得分:4)

运行此:

import dis
def f1():
  print(x if x else 'no x available')
def f2():
  print(x and x or 'no x available')
def f3():
  print(x or 'no x available')
dis.dis(f1)
dis.dis(f2)
dis.dis(f3)

我们得到f1

  4           0 LOAD_GLOBAL              0 (x)
              3 POP_JUMP_IF_FALSE       12
              6 LOAD_GLOBAL              0 (x)
              9 JUMP_FORWARD             3 (to 15)
        >>   12 LOAD_CONST               1 ('no x available')
        >>   15 PRINT_ITEM          
             16 PRINT_NEWLINE       
             17 LOAD_CONST               0 (None)
             20 RETURN_VALUE        

f2

  7           0 LOAD_GLOBAL              0 (x)
              3 POP_JUMP_IF_FALSE       12
              6 LOAD_GLOBAL              0 (x)
              9 JUMP_IF_TRUE_OR_POP     15
        >>   12 LOAD_CONST               1 ('no x available')
        >>   15 PRINT_ITEM          
             16 PRINT_NEWLINE       
             17 LOAD_CONST               0 (None)
             20 RETURN_VALUE        

取自@Klass Ivan的f3

 10           0 LOAD_GLOBAL              0 (x)
              3 JUMP_IF_TRUE_OR_POP      9
              6 LOAD_CONST               1 ('no x available')
        >>    9 PRINT_ITEM          
             10 PRINT_NEWLINE       
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE        

所以f1f2不一样。正如克拉斯所提到的那样,他们确实有不同的逻辑。 f3f1版本也有所不同,即使逻辑上它们应该是等效的,f3也可以省略一些操作。

答案 2 :(得分:4)

在实践中它们是相同的;理论上它们是不同的,但只有当__bool__方法有副作用时才会出现:

>>> class Weird:
    state = False
    def __bool__(self):
        self.state = not self.state
        return self.state


>>> x = Weird(); print(x if x else 'no x available')
<__main__.Weird object at 0x0000000003513160>
>>> x = Weird(); print(x and x or 'no x available')
no x available

如果你遇到这个理论案例,你可能会担心更糟糕的问题。

另请注意:

>>> x = Weird(); print(x or 'no x available')
<__main__.Weird object at 0x00000000035071D0>

所以Klass Ivan的回答在技术上是错误的。

底线,使用if表达式,因为它更清楚地表达了你的意思。

答案 3 :(得分:0)

代码方面我认为已经涵盖了这一点,但我会注意到你在这里所做的事情在语言上是非常不同的,并且可能对阅读你的代码的人有一个非常不同的影响,也许那些只是导航的潜意识网站的前端(即使是通过参与或代码知识的人也可能发现自己受到潜在的'符号链接'的心理影响*)。为了进一步解决这个问题,让我们考虑x的字符串值:

var x = "spoon";
print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')

仍然很难确切地看到“勺子”会发生什么,所以为了让事情更清楚,我们可以调用我们的变量“hasSpoon”而不是给它分配一个字符串(但你可以相信我们已经为它分配了一个字符串如果你喜欢,也可以使用“勺子”......):

print(hasSpoon if hasSpoon is true else 'no hasSpoon available')
# compared to:
print(hasSpoon and hasSpoon or 'no hasSpoon available')

正如我们所看到的,在第一种情况下,逻辑上的读数是我们的隐喻餐具持有人如果有勺子就有勺子,我认为我们可能会同意(另一方面他们有条件)没有勺子可供他们使用,而不是实际上没有一把有点奇怪的勺子,但可能,但是现在让我们把它放在一边。)

在第二个表达中,逻辑意义相当于我们的理论用餐者有一把勺子,还有一把勺子,这是一种其他方式的同义反复。

所以,如果你想向代码的任何潜在读者表达,以及任何可能受代理人影响的人,那些拥有勺子的人很可能会有勺子,而那些不喜欢勺子的人没有勺子的选择,你会使用第一个选项。另一方面,如果你想表达一个特定的人都有勺子和勺子,或者他们的条件是没有勺子打开他们,你会使用第二个表达。

或其他什么。

*我在这里象征性地使用这个术语,如果你原谅双关语。