Python 在布尔表达式中使用多个运算符

背景

众所周知,我们最好不要指定多个变量使用chain assignmentlike a = b = [1,2,3],因为这a将是b. 这是不安全的,因为a我们修改时会改变b。


但是,如果初始化是不可变的,我们可以这样做a = b = 1并且它是安全的。


最近,我发现在控制流的条件表达式中使用多个运算符很奇怪,比如if 1 < b < 2:orwhile a == b == c == 1:


例如,以下控制流在不同条件下执行不同的块:


a = 1

b = 1

c = 2


if a == b == c == 1:

    print('All equal!')

else:

    print('At least one variable is not equal to others')


至少一个变量不等于其他变量


我的问题

在控制流中的布尔表达式中,这种多重操作使用安全吗?我知道我们在编写布尔表达式时应该检查运算符的优先级。还有什么我们需要注意的吗?我尝试了一段时间,我认为多个运算符的使用是安全的。


字节码分析

我输入以下程序的字节码:


a = 1;b =2;c =1.5

a<b<c

import dis

dis.dis('a<b<c')

  1           0 LOAD_NAME                0 (a)

              2 LOAD_NAME                1 (b)

              4 DUP_TOP

              6 ROT_THREE

              8 COMPARE_OP               0 (<)

             10 JUMP_IF_FALSE_OR_POP    18

             12 LOAD_NAME                2 (c)

             14 COMPARE_OP               0 (<)

             16 RETURN_VALUE

>   18 ROT_TWO

             20 POP_TOP

             22 RETURN_VALUE```

我只能认识到它在第 10 步比较和,然后a在第 14 步比较和。但为什么它仍然返回。我不熟悉分析字节码。如果有人可以帮助分析它,我将不胜感激!这是Module的官方指南:disbacFalse


繁花如伊
浏览 145回答 2
2回答

海绵宝宝撒

这是你给的代码。a = 1b = 1c = 2if a == b == c == 1:&nbsp; &nbsp; print('All equal!')else:&nbsp; &nbsp; print('At least one variable is not equal to others')让我们了解它的含义。仅当它们三个都等于 时才a==b==c==1计算为. 否则评估为。被评估为。True1Falsea==b==ca==b and b==c and c==a为了得到你想要的,你必须这样做。if a==b==c==1:&nbsp; &nbsp; print('All are equal')elif (a==b) or (b==c) or (c==a):&nbsp; &nbsp;print('At least one variable is not equal to others')else:&nbsp; &nbsp; print('none of them are equal')现在分析您提供的第二个字节码。a = 1;b =2;c =1.5a<b<ca<b<c被评估为a<b and b<c在你的情况下 this is 1<2 and 2<1.5which is 被评估为False. 1<2被评估为True并且2<1.5被评估为False。True and假假is evaluated to`。字节码:In [2]: a=1;b=2;c=1.5In [3]: dis.dis('a<b and b<c')&nbsp; 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 COMPARE_OP&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (<)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 JUMP_IF_FALSE_OR_POP&nbsp; &nbsp; 14&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 (c)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 COMPARE_OP&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (<)&nbsp; &nbsp; &nbsp; &nbsp; >>&nbsp; &nbsp;14 RETURN_VALUE6 JUMP_IF_FALSE_OR_POP&nbsp; &nbsp; 14这行告诉我们的是如果为假则跳转到第 14 行。在逻辑 and False and any_bool_value上总是计算为False。现在 if 6 JUMP_IF_FALSE_OR_POP&nbsp; &nbsp; 14is Truethen 它继续执行8到14.在单个表达式中使用多个布尔运算符是安全的。

墨色风雨

from 0to 8it 比较a < b,at10检查其是否False,如果是 go to 18,则旋转堆栈,弹出顶部值,即False,因为a<b<cis a<b and b<c,所以如果第一个值为False,则不需要检查第二个条件。但在这种情况下a < b == True,它会继续。此时它已经通过了第一个检查点 ( 10),它知道第一个条件必须是True,所以它返回条件中的任何值b < c,即False,所以你得到False。相反,如果您检查 'a&nbsp; 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 COMPARE_OP&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (<)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 JUMP_IF_TRUE_OR_POP&nbsp; &nbsp; &nbsp;14&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 LOAD_NAME&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 (c)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 COMPARE_OP&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (<)&nbsp; &nbsp; &nbsp; &nbsp; >>&nbsp; &nbsp;14 RETURN_VALUE它做相反的事情,检查 ( 6) 如果第一个条件是True,如果是,则下一个条件的计算结果无关紧要并返回值,否则,返回下一个条件的计算结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python