你能在Python中使用不等于或等于简化链式比较吗?
你能在Python中使用不等于或等于简化链式比较吗?
这个问题已经有答案了:
可能有些人认为这是重复的问题,是的,我发现有很多类似的例子:
但是Pycharm告诉我可以简化一下:
if y > x and x != -1: # do something
我查了一些资料,没有找到类似的内容。
我的问题是,像这样简化这个函数是否正确:
if y > x != -1: # do something
如果这样做是正确的,那么它是否安全,并且与未简化版本之间是否存在任何区别,除了它更短?如果不能正确简化它,那么正确的方法是什么?
admin 更改状态以发布 2023年5月23日
这种写法与下面的写法在功能上等价,但是当你写成这样:
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
的情况下,你必须事先存储它。