为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁花如伊 2022-07-26 16:51:24
背景众所周知,我们最好不要指定多个变量使用chain assignmentlike a = b = [1,2,3],因为这a将是b. 这是不安全的,因为a我们修改时会改变b。但是,如果初始化是不可变的,我们可以这样做a = b = 1并且它是安全的。最近,我发现在控制流的条件表达式中使用多个运算符很奇怪,比如if 1 < b < 2:orwhile a == b == c == 1:例如,以下控制流在不同条件下执行不同的块:a = 1b = 1c = 2if a == b == c == 1:    print('All equal!')else:    print('At least one variable is not equal to others')至少一个变量不等于其他变量我的问题在控制流中的布尔表达式中,这种多重操作使用安全吗?我知道我们在编写布尔表达式时应该检查运算符的优先级。还有什么我们需要注意的吗?我尝试了一段时间,我认为多个运算符的使用是安全的。字节码分析我输入以下程序的字节码:a = 1;b =2;c =1.5a<b<cimport disdis.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
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

这是你给的代码。


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==b==c==1计算为. 否则评估为。被评估为。True1Falsea==b==ca==b and b==c and c==a


为了得到你想要的,你必须这样做。


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

    print('All are equal')

elif (a==b) or (b==c) or (c==a):

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

else:

    print('none of them are equal')

现在分析您提供的第二个字节码。


a = 1;b =2;c =1.5

a<b<c

a<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.5


In [3]: dis.dis('a<b and b<c')

  1           0 LOAD_NAME                0 (a)

              2 LOAD_NAME                1 (b)

              4 COMPARE_OP               0 (<)

              6 JUMP_IF_FALSE_OR_POP    14

              8 LOAD_NAME                1 (b)

             10 LOAD_NAME                2 (c)

             12 COMPARE_OP               0 (<)

        >>   14 RETURN_VALUE

6 JUMP_IF_FALSE_OR_POP    14这行告诉我们的是如果为假则跳转到第 14 行。在逻辑 and False and any_bool_value上总是计算为False。


现在 if 6 JUMP_IF_FALSE_OR_POP    14is Truethen 它继续执行8到14.


在单个表达式中使用多个布尔运算符是安全的。


查看完整回答
反对 回复 2022-07-26
?
墨色风雨

TA贡献1853条经验 获得超6个赞

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


  1           0 LOAD_NAME                0 (a)

              2 LOAD_NAME                1 (b)

              4 COMPARE_OP               0 (<)

              6 JUMP_IF_TRUE_OR_POP     14

              8 LOAD_NAME                1 (b)

             10 LOAD_NAME                2 (c)

             12 COMPARE_OP               0 (<)

        >>   14 RETURN_VALUE

它做相反的事情,检查 ( 6) 如果第一个条件是True,如果是,则下一个条件的计算结果无关紧要并返回值,否则,返回下一个条件的计算结果。


查看完整回答
反对 回复 2022-07-26
  • 2 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信