Учитывая 2 значения int, верните True, если один отрицательный, а другой положительный
def logical_xor(a, b): # for example, -1 and 1
print (a < 0) # evaluates to True
print (b < 0) # evaluates to False
print (a < 0 != b < 0) # EVALUATES TO FALSE! why??? it True != False
return (a < 0 != b < 0) # returns False when it should return True
print ( logical_xor(-1, 1) ) # returns FALSE!
# now for clarification
print ( True != False) # PRINTS TRUE!
Может кто-нибудь объяснить, что происходит? Я пытаюсь сделать один вкладыш:
lambda a, b: (a < 0 != b < 0)
Ответы
Ответ 1
Все операторы сравнения в Python имеют тот же самый приоритет. Кроме того, Python делает скованные сравнения. Таким образом,
(a < 0 != b < 0)
ломается как:
(a < 0) and (0 != b) and (b < 0)
Если какой-либо из них является ложным, итоговый результат выражения будет False
.
Что вы хотите сделать, так это оценить каждое условие отдельно:
(a < 0) != (b < 0)
Другие варианты, из комментариев:
(a < 0) is not (b < 0) # True and False are singletons so identity-comparison works
(a < 0) ^ (b < 0) # bitwise-xor does too, as long as both sides are boolean
(a ^ b < 0) # or you could directly bitwise-xor the integers;
# the sign bit will only be set if your condition holds
# this one fails when you mix ints and floats though
(a * b < 0) # perhaps most straightforward, just multiply them and check the sign
Ответ 2
Ваш код не работает должным образом, потому что !=
принимает более высокий precedence, чем a < 0
и b < 0
, Как предполагает Ицмеонтв в своем ответе, вы можете просто решить приоритет самостоятельно, окружая логические компоненты круглыми скобками:
(a < 0) != (b < 0)
Ваш код пытается оценить a < (0 != b) < 0
[EDIT]
Как правильно указывает tzaman, операторы имеют одинаковый приоритет, но ваш код пытается оценить (a < 0) and (0 != b) and (b < 0)
. Окружающие ваши логические компоненты круглыми скобками разрешат это:
(a < 0) != (b < 0)
Приоритет оператора: https://docs.python.org/3/reference/expressions.html#operator-precedence
Сравнение (например, цепочка): https://docs.python.org/3/reference/expressions.html#not-in
Ответ 3
Вы можете использовать этот
return (a < 0) != (b < 0)
Сравнение может быть скоблено произвольно, например, x < y <= z эквивалентно x < y и y <= z, за исключением того, что y оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y считается ложным).
Таким образом, он становится
(a < 0) and (0 != b) and (b < 0)
См. https://docs.python.org/3/reference/expressions.html#not-in
Ответ 4
В Python операторы сравнения имеют одинаковый приоритет и неассоциативны. Существует отдельное правило для последовательностей операторов сравнения, правила цепочки. Документация Python утверждает следующее:
если a, b, c, ..., y, z
- выражения, а op1, op2, ..., opN
- операторы сравнения, то a op1 b op2 c ... y opN z
эквивалентно a op1 b and b op2 c and ... y opN z
, за исключением того, что каждое выражение оценивается не более одного раза.
Далее, a op1 b and b op2 c and ... y opN z
оценивается слева направо.
a < 0 and 0 != b and b < 0
a < 0
будет оцениваться до False
, и дальнейшая оценка будет остановлена из-за оценки короткого замыкания. Таким образом, все выражение будет оцениваться как False
.