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

Can you simplify chained comparisons with not equal or equal in Python?

本问题已经有最佳答案,请猛点这里访问。

也许你们中的一些人会认为这是重复的,是的,我发现了很多类似的例子:enter image description here

但是Pycharm说我可以这么简单:

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

我做了一些搜索,找不到类似的东西。我的问题是这样简化这个函数是正确的:

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

如果是这样的话,它安全吗?这个版本和非简化版本之间有什么区别吗,除了它较短之外?如果简化它的方法不正确,那又是什么呢?


这是功能等效的,但当:

1
10 < x < 40

很好阅读,混合不同的运算符使用链接比较不是最佳选择。

真的一样吗?让我们拆开看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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版本,它的快捷方式和可读性都非常强(想想未来的维护人员…)。

也就是说,链比较的一个有趣之处在于,如果计算中心参数/需要很长时间来计算/在计算中有副作用,并且不希望将其存储在变量中:

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

在这种情况下,中心参数只计算一次。如果是and,您必须事先存储它。