Вероятно, некоторые из вас могут подумать, что это дубликат, и да, я нашел много примеров, подобных этому:
Но Pycharm говорит, что я могу просто это:
if y > x and x != -1:
# do something
И я искал и не мог найти что-то подобное. Мой вопрос: правильно ли упростить эту функцию следующим образом:
if y > x != -1:
# do something
И если это так, безопасно ли и существует ли какая-либо разница между этой версией и не упрощенной версией, за исключением того, что она короче? Если это не правильный способ его упростить, то что тогда?
это функционально эквивалентно, но когда это:
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
, вам придется хранить его заранее.
x
, что может быть выражением типа x**2
, которое он будет вычислять только один раз