你能在Python中使用不等于或等于简化链式比较吗?

24 浏览
0 Comments

你能在Python中使用不等于或等于简化链式比较吗?

这个问题已经有答案了

简化链接比较

Python中链接比较是如何工作的?

可能有些人认为这是重复的问题,是的,我发现有很多类似的例子:

\"enter

但是Pycharm告诉我可以简化一下:

if y > x and x != -1:
    #  do something

我查了一些资料,没有找到类似的内容。

我的问题是,像这样简化这个函数是否正确:

if y > x != -1:
    #  do something

如果这样做是正确的,那么它是否安全,并且与未简化版本之间是否存在任何区别,除了它更短?如果不能正确简化它,那么正确的方法是什么?

admin 更改状态以发布 2023年5月23日
0
0 Comments

这种写法与下面的写法在功能上等价,但是当你写成这样:

10 < x < 40

看起来很不错,但是混合不同的操作符来进行连锁比较并不是最好的选择。

这真的一样吗?让我们来反汇编一下来找出答案:

def f1(x,y):
    if y > x and x != -1:
        return 0
def f2(x,y):
    if y > x != -1:
        return 0
import dis
print("function 1")
dis.dis(f1)
print("function 2")
dis.dis(f2)

结果是:

function 1
  2           0 LOAD_FAST                1 (y)
              3 LOAD_FAST                0 (x)
              6 COMPARE_OP               4 (>)
              9 POP_JUMP_IF_FALSE       28
             12 LOAD_FAST                0 (x)
             15 LOAD_CONST               3 (-1)
             18 COMPARE_OP               3 (!=)
             21 POP_JUMP_IF_FALSE       28
  3          24 LOAD_CONST               2 (0)
             27 RETURN_VALUE
        >>   28 LOAD_CONST               0 (None)
             31 RETURN_VALUE
function 2
  6           0 LOAD_FAST                1 (y)
              3 LOAD_FAST                0 (x)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               4 (>)
             11 JUMP_IF_FALSE_OR_POP    23
             14 LOAD_CONST               3 (-1)
             17 COMPARE_OP               3 (!=)
             20 JUMP_FORWARD             2 (to 25)
        >>   23 ROT_TWO
             24 POP_TOP
        >>   25 POP_JUMP_IF_FALSE       32
  7          28 LOAD_CONST               2 (0)
             31 RETURN_VALUE
        >>   32 LOAD_CONST               0 (None)
             35 RETURN_VALUE
>>> 

令人惊讶的是,它们并不相同,而且连锁版本具有更多的指令。

不太清楚这里发生了什么事情(有些人花了更多的时间来更好地解释它:Python 中连锁比较的实际工作方式是什么?),但实际上我会坚持使用 and 版本,这样代码可读性更强(也要考虑未来的维护者…)。

话虽如此,连锁比较一个有趣的方面是:如果中心参数是计算/需要很长时间来计算/在计算中具有副作用,并且你不想将其存储在变量中:

if y > super_long_computation(x) != -1:

在这种情况下,中心参数只计算一次。在使用 and 的情况下,你必须事先存储它。

0