以下是否有任何区别?
print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')
答案 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
所以f1
和f2
不一样。正如克拉斯所提到的那样,他们确实有不同的逻辑。 f3
和f1
版本也有所不同,即使逻辑上它们应该是等效的,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')
正如我们所看到的,在第一种情况下,逻辑上的读数是我们的隐喻餐具持有人如果有勺子就有勺子,我认为我们可能会同意(另一方面他们有条件)没有勺子可供他们使用,而不是实际上没有一把有点奇怪的勺子,但可能,但是现在让我们把它放在一边。)
在第二个表达中,逻辑意义相当于我们的理论用餐者有一把勺子,还有一把勺子,这是一种其他方式的同义反复。
所以,如果你想向代码的任何潜在读者表达,以及任何可能受代理人影响的人,那些拥有勺子的人很可能会有勺子,而那些不喜欢勺子的人没有勺子的选择,你会使用第一个选项。另一方面,如果你想表达一个特定的人都有勺子和勺子,或者他们的条件是没有勺子打开他们,你会使用第二个表达。
或其他什么。
*我在这里象征性地使用这个术语,如果你原谅双关语。