假设我们想要在'a'和'b'都等于5时执行一些代码块.然后我们可以这样编写:
if a == 5 and b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
但是几天前,我只是不由自主地写了一个类似的条件检查:
if a == b and b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
这让我想到,两者之间有什么区别吗?另外,还有另一种方式,
if a == b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
是否存在任何差异,评估或执行过程或所花费的时间有何不同?还有哪一个更好或哪个更好?
它与传递性的概念有关吗?
Jas*_*per 43
由于它们基本相同,您还可以考虑您阅读/思考代码的方式:
if a == 5 and b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
可以读作"如果a
等于5
和b
等于5
,那么......".你必须思考/总结,那也a
将等于b
.
这与下一个例子相反:
if a == b and b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
这读作"if a
等于b
和b
等于5
",你必须得出结论,那么它也a
将等于5
这就是为什么我更喜欢最后一个例子:
if a == b == 5:
# do something
Run Code Online (Sandbox Code Playgroud)
如果你熟悉Python(感谢Itzkata),很明显所有三件事都必须相同(to 5
).然而,如果人们对Python经验不足(但其他语言的编程技能)看到了这一点,他们可能会对此进行评估
if (a == b) == 5:
Run Code Online (Sandbox Code Playgroud)
这将比较第一次比较的布尔结果与整数5,这不是Python所做的,可能会导致不同的结果(例如考虑a=0, b=0
:a==b==0
是,而(a==b) == 0
不是!
该手册说:
Python中有八个比较操作.它们都具有相同的优先级(高于布尔操作的优先级).比较可以任意链接; 例如,x <y <= z等效于x <y和y <= z,除了y仅被评估一次 (但在两种情况下,当x <y被发现为假时,根本不评估z).
甚至可能存在差异,例如,如果b
在您的示例中进行评估会产生副作用.
关于传递性,你是对的.
dev*_*ull 20
如果您有更多要测试的变量,使用all
可能会稍微更具可读性:
if all(i==5 for i in [a,b,c,d]):
# do something
Run Code Online (Sandbox Code Playgroud)
Rob*_*ale 15
就整数而言,在前两个比较之间,就纯粹的表现而言,没有区别.
但第三种比较是不同的; 因为更多的摆弄堆栈涉及到.的确,代码
import dis
def comparison_1(a, b):
if a == 5 and b == 5:
pass
def comparison_2(a, b):
if a == b and b == 5:
pass
def comparison_3(a, b):
if a == b == 5:
pass
print("*** First comparison ***")
dis.dis(comparison_1)
print("\n*** Second comparison ***")
dis.dis(comparison_2)
print("\n*** Third comparison ***")
dis.dis(comparison_3)
Run Code Online (Sandbox Code Playgroud)
回报
*** First comparison ***
4 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (5)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 27
12 LOAD_FAST 1 (b)
15 LOAD_CONST 1 (5)
18 COMPARE_OP 2 (==)
21 POP_JUMP_IF_FALSE 27
5 24 JUMP_FORWARD 0 (to 27)
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
*** Second comparison ***
8 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 27
12 LOAD_FAST 1 (b)
15 LOAD_CONST 1 (5)
18 COMPARE_OP 2 (==)
21 POP_JUMP_IF_FALSE 27
9 24 JUMP_FORWARD 0 (to 27)
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
*** Third comparison ***
12 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 2 (==)
11 JUMP_IF_FALSE_OR_POP 23
14 LOAD_CONST 1 (5)
17 COMPARE_OP 2 (==)
20 JUMP_FORWARD 2 (to 25)
>> 23 ROT_TWO
24 POP_TOP
>> 25 POP_JUMP_IF_FALSE 31
13 28 JUMP_FORWARD 0 (to 31)
>> 31 LOAD_CONST 0 (None)
34 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
这取决于.您可以编写自己的自定义__eq__
,以便将自己与整体和事物进行比较:
class NonNegativeInt(object):
def __init__(self, value):
if value < 0:
raise Exception("Hey, what the...")
self.value = value
def __eq__(self, that):
if isinstance(that, int):
return self.value == that
elif isinstance(that, NonNegativeInt):
return self.value == that.value
else:
raise ArgumentError("Not an acceptible argument", "__eq__", that)
Run Code Online (Sandbox Code Playgroud)
根据将"b"与"a"和"b"与"int"进行比较,哪种方法会有所不同.因此,a == b
可能是假的,而a == 5 and b == 5
可能是真的.
归档时间: |
|
查看次数: |
59334 次 |
最近记录: |